安全发布对象的常用模式
发布一个对象时,对象的引用和对象的状态必须同时对其他线程可见,以下方式可以实现、
1.在静态初始化函数中初始化一个对象引用
2.将对象的引用保存到volatile类型给的域或AtomicReferance对象中
class VolatileExample{
volatile private VolatileExample example; //保证不会指令重排,保证可见性
public void initializeExample(){
example = new VolatileExample(); //安全发布 只考虑一个线程调用创建对象 另一个线程使用doSomething方法
}
public void doSomething(){ //其他线程直接用类的实例调用方法不会出错
}
}
3.将对象的引用保存到某个正确构造对象的final类型域中
class VolatileExample{
private final VolatileExample example; //保证初始化过程的安全性 且访问不受限制(若example为不可变对象)
public void initializeExample(){
example = new VolatileExample(); //安全发布 只考虑一个线程调用创建对象 另一个线程使用doSomething方法
}
public void doSomething(){ //其他线程直接用类的实例调用方法不会出错
}
}
4.将对象的引用保存到一个由锁保护的域中
例如:HashTable,ConcurrentMap,synchronizedSet等安全的容器中
最简单最安全的方式发布静态构造对象的方法:
public static Holder holder = new Holder();