【问题标题】:Does volatile propagate to instance members?volatile 是否会传播到实例成员?
【发布时间】:2015-07-12 10:59:20
【问题描述】:

假设有一些像这样声明和实例化的简单容器

class Test {
    private volatile List<Object> list = new ArrayList<>();
}

,对其的读写都有锁保护; synchronized 关键字未使用。尽管Test.list 被声明为 volatile,但它的成员字段(如ArrayList.elementData)都没有这个修饰符。现在,在多线程应用程序中,它的行为会像 volatile 容器吗?换句话说,某个线程提交给ArrayList.elementData的更改是否会立即被所有其他线程看到?

【问题讨论】:

标签: java multithreading volatile


【解决方案1】:

一般的答案是否定的:volatile 仅在对引用变量的读取和写入之间建立发生前的关系。如果两个线程同时访问变量中引用的对象的一个​​内部字段,仍然需要有一个同步机制。

在您的情况下,最好的方法似乎是使用同步列表,或 java.util.concurrent 包中的一些包装器。

【讨论】:

    【解决方案2】:

    简短的回答:不。因此,数组元素始终是非易失性的(即使数组本身被声明为易失性)。您需要使用List 的特殊并发友好实现。通常java.util.concurrent.CopyOnWriteArrayList 适合需求。如果你只分配了一次list 变量,那么 volatile 关键字不会改变任何东西(在这种情况下最好使用final)。

    【讨论】:

    • 即使数组本身声明为volatile。这是一种误导,因为您将数组variable 与数组object 混为一谈。当有人说“数组”时,他们通常是在谈论对象;但对象不能是volatile。只有一个变量可以是volatile。当我们与经验丰富的开发人员交谈时,我们可以避免这种谈话,但这种情况下的 OP 显然对对象和变量之间的区别理解很薄弱。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-07
    • 2015-08-23
    相关资源
    最近更新 更多