首先建一个单例模式的多线程情况
public class SingletonDemo {
private static SingletonDemo instance = null;
private SingletonDemo(){
System.out.println(Thread.currentThread().getName()+ "\t 我是构造方法singletonDemo()") ;
}
public static SingletonDemo getInstance(){
if (instance == null )
{
instance = new SingletonDemo();
}
return instance;
}
public static void main(String[] args) {
// 单线程
// System.out.println(SingletonDemo.getInstance() == SingletonDemo.getInstance());
// System.out.println(SingletonDemo.getInstance() == SingletonDemo.getInstance());
//
// System.out.println(SingletonDemo.getInstance() == SingletonDemo.getInstance());
// 多线程
for (int i = 1; i <= 10; i++){
new Thread(() -> {
SingletonDemo.getInstance();
},String.valueOf(i)).start();
}
}
}
当运行这份代码的时候会出现这种情况
我们可以改为
// DCL (Double Check Lock 双端检锁机制)
public static SingletonDemo getInstance(){
if (instance == null )
{
synchronized (SingletonDemo.class){
if (instance == null){
instance = new SingletonDemo();
}
}
}
return instance;
}
但这种也会出现问题,原因就是指令重排,为什么会出现这种问题呢?
当一条线程访问instance不为null时,由于instance实例未必已初始化完成,也就造成了线程安全问题
怎么办呢.可以加上volatile就可以了.