问题
不同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虚拟机实现会产生的上述问题。