1、引入
单例模式想必有过编程经验的或多或少有所耳闻,如标题所言,对于单例模式而言,一个类只会存在一个对象,每次调用都是对该对象进行操作。
2、实例
单例模式通常被分为饿汉式和懒汉式
- 饿汉式:如其名,为了防止饥饿,会把食物(单例)预先准备好
- 懒汉式:如其名,由于懒惰,到了要使用的时候发现没有,才会将食物做出来
2.1、饿汉式实现
public class HungrySingleton {
private static HungrySingleton singleton=new HungrySingleton();
private HungrySingleton() {
System.out.println("饿汉式生成实例");
}
public static HungrySingleton getInstance() {
return singleton;
}
}
2.2、懒汉式实现
public class LazySingleton {
private static LazySingleton singleton;
private LazySingleton() {
System.out.println("懒汉式生成实例");
}
private static LazySingleton getInstance() {
if (singleton != null) {
singleton=new LazySingleton();
}
return singleton;
}
}
3、tips
-
在未加防护措施情况下,在多线程中懒汉式实现是线程不安全的:可能存在两次调用几乎同时对singleton进行创建。可以使用synchronize关键字或是双检锁(推荐)来进行防护。
-
一般来说,懒汉式和饿汉式的的应用场景可以如此区分:
- 频繁调用getInstance()的情况下建议使用饿汉式,懒汉式由于判断是否为null会比饿汉式多耗费事件
- 在多线程环境下建议使用饿汉式,减少线程同步的开销
- 在较不常使用该单例类的时候可以使用懒汉式,由于懒汉式到使用才加载对象,能够减少类加载事件
-
在许多框架中如Spring的IOC中大量使用到了单例模式。