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 statement
	private AtomicInteger atomicInteger = new AtomicInteger(0);
	
	private 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 resource
				if(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;
	}
	
}


对于多线程编程时,我们可以考虑使用java.util.concurrent.atomic.*包下的一系列
确保原子操作对象来实现原子操作,以排除不同Java虚拟机实现会产生的上述问题。

你可能感兴趣的:(java)