volatile是否传播给实例成员?

时间:2015-07-12 10:59:20

标签: java multithreading volatile

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

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

,对它的读写操作由锁保护;未使用synchronized个关键字。虽然Test.list被声明为volatile,但其ArrayList.elementData之类的成员字段也不具有此修饰符。现在,在多线程应用程序中,它会像volatile容器一样吗?换句话说,某些线程提交给ArrayList.elementData的更改是否会被所有其他线程立即看到?

2 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:2)

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