对于Java中的非原始值,volatile关键字是否无关紧要?

时间:2015-07-16 16:52:41

标签: java multithreading concurrency

如果我有一个ArrayList被两个不同的线程访问,我知道使用int,你冒着读取线程缓存并接收错误号码的风险。使用ArrayList,线程的缓存只会存储对数组的引用吗?这意味着当从任一线程访问时,ArrayList中的值是否一致?

2 个答案:

答案 0 :(得分:4)

  

使用ArrayList,线程的缓存是否只存储对数组的引用?

写入ArrayList的volatile只影响对列表字段的赋值,而不影响列表本身的变异(通过addremove)。

  

意味着ArrayList中的值在何时是一致的   从任何一个线程访问?

没有。对列表进行任何修改都会产生与非易失性写入相同的风险,因为volatile只会影响volatile字段的分配。

您可以将ArrayList定义为final,并获得相同的内存保证,如果将其添加到列表或从中删除,则会将其定义为volatile

答案 1 :(得分:0)

volatile关键字不仅保证非陈旧读取和原子访问(防止单词撕裂,特别是在32位平台上),还提供ordering guarantees,建立happens-before关系。

正常字段读/写不执行此操作,这意味着如果将数组列表引用写入非易失性字段而另一个线程读取它,则可能最终会看到数组列表内部处于不一致状态,因为写入与其他写入重新排序。