对于以下简化的类:

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++;
    }
    ...
}

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

最佳答案

没错,在构造函数中没有synchronized块,就无法保证非最终字段的可见性,如this example所示。

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

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

关于构造函数中的Java内存可见性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33702625/

10-12 13:49