在http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html的底部,它说:
Double-Checked Locking Immutable Objects
If Helper is an immutable object, such that all of the fields of Helper are final, then double-checked locking will work without having to use volatile fields. The idea is that a reference to an immutable object (such as a String or an Integer) should behave in much the same way as an int or float; reading and writing references to immutable objects are atomic.
mutable的示例和解释如下:
// Broken multithreaded version
// "Double-Checked Locking" idiom
class Foo {
private Helper helper = null;
public Helper getHelper() {
if (helper == null)
synchronized(this) {
if (helper == null)
helper = new Helper();
}
return helper;
}
// other functions and members...
}
The first reason it doesn't work
The most obvious reason it doesn't work it that the writes that initialize the Helper object and the write to the helper field can be done or perceived out of order. Thus, a thread which invokes getHelper() could see a non-null reference to a helper object, but see the default values for fields of the helper object, rather than the values set in the constructor.
If the compiler inlines the call to the constructor, then the writes that initialize the object and the write to the helper field can be freely reordered if the compiler can prove that the constructor cannot throw an exception or perform synchronization.
Even if the compiler does not reorder those writes, on a multiprocessor the processor or the memory system may reorder those writes, as perceived by a thread running on another processor.
我的问题是:为什么不可变类没有问题?我看不出重新排序与类是否可变有任何关系。
谢谢
最佳答案
对于普通对象,代码被“破坏”的原因是 helper
可能是非空的,但指向一个尚未完全初始化的对象,正如所解释的在你的报价中。
然而,如果 Helper 类是不可变的,这意味着它的所有字段都是最终的,the Java Memory Model保证它们被安全发布,即使对象通过数据竞争可用(在您的示例中就是这种情况):
final
fields also allow programmers to implement thread-safe immutable objects without synchronization. A thread-safe immutable object is seen as immutable by all threads, even if a data race is used to pass references to the immutable object between threads. This can provide safety guarantees against misuse of an immutable class by incorrect or malicious code.final
fields must be used correctly to provide a guarantee of immutability.
关于java - 为什么不可变对象(immutable对象)在双重检查锁定中是安全的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26611892/