单例模式在设计模式中比较常见,在多线程访问的时候容易出现线程不安全的隐患
懒汉式(延迟加载)/饿汉式(立即加载)
直接给出双检查锁单例模式
public class Singleton {
private static Singleton instance;
private Singleton (){
}
public static Singleton getInstance(){
if (instance == null){
synchronized(Singleton.class){
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
问题根源在此:
new对象可拆分成3个指令执行
1、memory = allocate() //分配内存
2、ctorInstance(memory) //初始化对象
3、instance = memory //instance指向刚分配的内存地址
其中2和3可能会指令重排,如果发生指令重排,先执行了指令3,此时线程2执行第一个if判断时就是false,此时直接返回一个没有初始化的instance对象,导致系统错误
所以应加上volatile禁止重排序
public class Singleton {
private volatile static Singleton instance;
private Singleton (){
}
public static Singleton getInstance(){
if (instance == null){
synchronized(Singleton.class){
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}