Gee*_*eek 16 java java-memory-model
从Java并发实践中的书:
要安全地发布对象,必须同时使对象的引用和对象的状态对其他线程可见.正确构造的对象可以通过以下方式安全发布:
从静态初始化程序初始化对象引用
将对它的引用存储到volatile字段或AtomicReference中
将对它的引用存储到正确构造的对象的最终字段中
将对它的引用存储到由
锁正确保护的字段中.
我的问题是:
volatile方法和final方法在安全发布对象方面的区别感兴趣.this引用转义).但他们为什么再次提到正确构造的物体呢?ass*_*ias 12
子弹点2和3之间有什么区别?
volatile基本上意味着对该字段的任何写入都将从其他线程中可见.因此,当您将字段声明为volatile:时private volatile SomeType field;,可以保证如果构造函数写入该字段:field = new SomeType();此随后尝试读取的其他线程将显示此分配field.final具有非常相似的语义:您可以保证如果您有一个final字段:private final SomeType field;写入该字段(在声明或构造函数中):field = new SomeType();将不会被重新编码并且如果对象正确则将被其他线程看到发表(this例如,没有逃脱).显然,主要的不同之处在于,如果该字段是最终的,则只能分配一次.
在第3点中,正确构造的物体的最终场是什么意思?
例如,如果您this从构造函数中退出,则最终语义提供的保证将消失:观察线程可能会看到该字段的默认值(对象为null).如果对象构造正确,则不会发生这种情况.
举例:
class SomeClass{
private final SomeType field;
SomeClass() {
new Thread(new Runnable() {
public void run() {
SomeType copy = field; //copy could be null
copy.doSomething(); //could throw NullPointerException
}
}).start();
field = new SomeType();
}
}
Run Code Online (Sandbox Code Playgroud)