初级单例模式的实现
实现单例模式注意点:既然不能通过构造方法创建实例,那么必须通过一个get方法来获得,那么这个get方法必须是静态的方法,否则这个实例只能通过反射创建了。
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
分析:显然这是一个单例模式的实现,但是它线程不安全,测试一下,用10个线程调用getInstance方法,结果在这次测试中产生了3个Singleton对象:
那么怎么解决呢?
方法一:
加同步锁:
同步锁可以加在哪些位置呢:
- get方法上:让get方法变成同步方法,但是我们的目的其实只是想锁住单例资源,把整个方法锁住的话,虽然简单粗暴,但是太笨重了
- 双重检查法+同步锁:因为单重判断要么不能解决线程安全问题,要么每次都会有加锁的行为,使整个方法变重。
public class Singleton {
static Object object = new Object();
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (object) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
方法二:
静内部类(最优):
public class Singleton {
private Singleton(){}
//静态内部类实现线程安全的单例模式
private static class SingletonHolder{
static Singleton instance = new Singleton();
}
public static Singleton getInstance(){
return SingletonHolder.instance;
}
}