构造函数中的Java内存可见性

nik*_*pen 6 java memory concurrency

对于以下简化类:

public class MutableInteger {
    private int value;
    public MutableInteger(int initial) {
        synchronized(this) { // is this necessary for memory visibility?
            this.value = initial;
        }
    }
    public synchronized int get() {
        return this.value;
    }
    public synchronized void increment() {
        this.value++;
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

我想一般的问题是同步保护的可变变量是否需要在构造函数中设置初始值时进行同步?

biz*_*lop 4

你是对的,如果构造函数中没有块,就没有非最终字段的可见性保证,如本示例synchronized所示。

然而在实践中,我宁愿在这种情况下使用volatile字段或类。Atomic*

更新:这里还需要提到的是,为了使您的程序correctly synchronized(由 JLS 定义),您需要以安全的方式发布对对象的引用。引用的示例没有这样做,因此您可能会在非最终字段中看到错误的值。但是,如果您正确发布对象引用(即通过将其分配给final另一个对象的字段,或者在调用之前创建它Thread.start()),则可以保证您的对象至少会被视为与发布时一样最新,因此使得synchronized构造函数中的块变得不必要。