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

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

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

最佳答案

你是对的,如果构造函数中没有 synchronized block ,就无法保证非最终字段的可见性,如 this example 中所示。 .

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

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

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

相关文章:

java - 无法使用 java Udp 获得响应

android - android中的dalvik堆和 native 堆有什么区别?哪一个是固定的。?

c - 取消引用 C 中的函数指针以访问 CODE 内存

scala - 同时处理具有重复项的序列

java - 线程执行期间(/之后)数据的可见性

java - 从 Unix 时间到 Java 日历的转换

java - 所以在java中你不能有不同的返回值和参数的重复方法名?

java - 对学习 Java 并发的程序或小项目有什么建议吗?

java - 将字符串拆分为字符串数组

object - 返回 interface{} 而不是 int64 时的额外分配