Java单例模式 以原子操作方式的实现
问题
不同Java虚拟机实现产生有引用未构造问题
Java虚拟机初始化对象时,分析如下
SomeObject so = new SomeObject();
Java虚拟机JVM
指令
so ====> memory A步骤
.
. =====> construct--执行构造 B步骤
.
. =====> asign -----指定其他的引用,或者实例化so中的其他变量 C步骤
. .
. . 其他步骤
. .
当一个线程执行到 步骤A 时,另一个线程访问 so对象
如 SomeObject getSo()
此时 getSo() 返回 so对象的引用不为空
我们拿着一个so对象引用去获取so对象中的另一个属性,比如so.getOtherAttribute()
这个时候这个OtherAttribute在构造器中或其他步骤中,并没有执行完成,这将
会导致一个运行时异常。
我用一个单例模式的实现来说明此类问题的解决方法
package test;import java.util.concurrent.atomic.AtomicInteger;import java.util.concurrent.atomic.AtomicReference;public class AtomicSingleton {private static AtomicReference<AtomicSingleton> atomicReference = new AtomicReference<AtomicSingleton>();//test how constructor get into by new AtomicSingleton statementprivate AtomicInteger atomicInteger = new AtomicInteger(0);public AtomicSingleton(){int i = atomicInteger.get();atomicInteger.addAndGet(i++);}public static AtomicSingleton getInstance(){AtomicSingleton atomicSingleton = atomicReference.get();if(null != atomicSingleton){synchronized (AtomicSingleton.class) {//double checking the AtomicSingleton whether initial, ensure not new AtomicSingleton twice //to waste the system resourceif(null!=(atomicSingleton=atomicReference.get())){return atomicSingleton;}//ensure the locate the memory, construct and other instructs is atomic, //whatever the implementation of the JVM atomicReference.getAndSet(new AtomicSingleton());//atomicReference.compareAndSet(null, new AtomicSingleton());atomicSingleton = atomicReference.get();}}return atomicSingleton;}}