对于以下简化类:
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
block ,就无法保证非最终字段的可见性,如 this example 中所示。 .
但在实践中,我宁愿在这种情况下使用 volatile
字段或 Atomic*
类。
更新:这里还需要注意的是,为了让您的程序正确同步
(由 JLS 定义),您需要发布以安全的方式引用您的对象。引用的示例没有这样做,因此您可能会在非最终字段中看到错误的值。但是如果你正确地发布对象引用(即通过将它分配给另一个对象的 final
字段,或者通过在调用 Thread.start()
之前创建它),它是保证您的对象至少与发布时一样是最新的,因此不需要构造函数中的 synchronized
block 。
关于构造函数中的 Java 内存可见性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33702625/