java - 为什么不可变对象(immutable对象)在双重检查锁定中是安全的?

标签 java thread-safety immutability double-checked-locking

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/

相关文章:

java - Android 屏幕上精确坐标处的图标

java - 从 Web 应用程序运行 Ant 任务 - JBoss 部署工具

objective-c - 从 objective-c 中的 @synchronized block 内部返回

ios - Swift 中的不可变/可变集合

c++ - 如何在 C++ 中实现不可变字符串?

java - Spring找不到bean

java - ConcurrentHashMap<Integer, ArrayList<Object>> 线程安全吗?

android - 服务关闭时的操作顺序

haskell - 用于 CLI 应用程序的 Haskell 中的 IO 状态

java - 在应用程序中设置应用程序特定属性