volatile 会传播到实例成员吗?

Does volatile propagate to instance members?

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

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

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

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

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

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