java并发编程笔记(四)——安全发布对象
发布对象
使一个对象能够被当前范围之外的代码所使用
对象逸出
一种错误的发布。当一个对象还没构造完成时,就使它被其他线程所见
不安全的发布对象
某一个类的构造方法为公共的。
如:
public class UnsafePublish {
private String[] states = {"a", "b", "c"};
public String[] getStates() {
return states;
}
public static void main(String[] args) {
UnsafePublish unsafePublish = new UnsafePublish(); //这行代码,发布了一个实例
log.info("{}", Arrays.toString(unsafePublish.getStates()));
unsafePublish.getStates()[0] = "d";
log.info("{}", Arrays.toString(unsafePublish.getStates()));
}
}
对象逸出的案例:
public class Escape {
private int thisCanBeEscape = 0;
public Escape () {
new InnerClass();
}
private class InnerClass {
public InnerClass() {
log.info("{}", Escape.this.thisCanBeEscape);
}
}
public static void main(String[] args) {
new Escape();
}
}
安全的发布对象
- 在静态初始化函数中初始化一个对象运用
- 将对象的引用保存到volatile类型域或者AtomicReference对象中
- 将对象的引用保存到某个正确的构造对象的final类型域中
- 将对象的引用保存到一个由锁保护的域中
volatile使用场景
- 修饰装填码,保证操作原子性
- 双重检测机制中,防止指令重排序