从实践中的Java并发性书中:
我的问题是:
volatile
方法和final
方法之间的区别感兴趣。 this
引用转义)。但是他们又为什么提到适当构造的对象呢? 最佳答案
volatile
基本上意味着对该字段的任何写入将在其他线程中可见。因此,当您将字段声明为volatile:private volatile SomeType field;
时,可以确保如果构造函数写入该字段:field = new SomeType();
,则随后尝试读取field
的其他线程将看到此分配。 final
的语义非常相似:如果有一个最终字段,则可以保证:private final SomeType field;
对字段的写入(无论是在声明中还是在构造函数中):field = new SomeType();
将不会被重新编排,并且在其他线程中可见该对象已正确发布(例如,不能逃脱this
)。 显然,主要区别在于,如果该字段为final,则只能分配一次。
例如,如果让
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();
}
}