一 场景
在多线程场景下,当一个线程判断instance为null时 ,他会新建一个实例,那么问题来了,当A线程发现对象实例为空时,准备
新建一个实例,这时cpu轮询到B线程,B线程也察觉对象实例为空,它也会新建一个实例,这样就破坏了单例模式。
二 解决方案
首先对象实例必须是全局共享的,用volatile修饰,然后在判断对象实例为空之后要将创建一个工厂方法的同步锁,在其中再判断一次实例是否为空,这样当A线程持有对象锁创建实例后,B线程拿到锁他会再次判断是否存在实例对象,这时A线程已经创建实例,所以可以保证单例。
代码
public class SingletonClass { private volatile static SingletonClass instance = null; public static SingletonClass getInstance() { if (instance == null) { //如果存在实例就不进入同步块 提高效率 synchronized (SingletonClass.class) { if(instance == null) { instance = new SingletonClass(); } } } return instance; } private SingletonClass() { } }