假设有一个简单的容器声明并像这样实例化
class Test {
private volatile List<Object> list = new ArrayList<>();
}
,对它的读写操作由锁保护;未使用synchronized
个关键字。虽然Test.list
被声明为volatile,但其ArrayList.elementData
之类的成员字段也不具有此修饰符。现在,在多线程应用程序中,它会像volatile容器一样吗?换句话说,某些线程提交给ArrayList.elementData
的更改是否会被所有其他线程立即看到?
答案 0 :(得分:5)
一般答案是否:volatile
仅建立读取和写入引用变量之间的先发生关系。如果两个线程同时访问变量中引用的对象的内部字段,则仍需要一个同步机制。
在您的情况下,最佳方法似乎使用同步列表或java.util.concurrent
包中的一些包装。
答案 1 :(得分:2)
简答:不。因此,数组元素总是非易失性的(即使数组本身被声明为volatile)。您需要使用List
的特殊并发友好实现。通常java.util.concurrent.CopyOnWriteArrayList
符合需求。如果您只为list
变量分配一次,则volatile关键字不会更改任何内容(在这种情况下,最好使用final
)。