为什么
HashMap
不使用volatile
来修改modCount
以确保当另一个线程更改它时,一个线程可以立即知道Map
的变化?
以下片段:
/**
* The number of times this HashMap has been structurally modified
* Structural modifications are those that change the number of mappings
in
* the HashMap or otherwise modify its internal structure (e.g.,
* rehash). This field is used to make iterators on Collection-views of
* the HashMap fail-fast. (See ConcurrentModificationException).
*/
transient int modCount;
将
modCount
声明为 volatile
的唯一好处是使并发修改的“快速失败”检测更快......在某些情况下:
对于线程受限的
HashMap
(即仅由一个线程使用),没有任何功能上的好处。该线程保证可以看到它对 modCount
所做的更新。对于不受线程限制但以其他方式(正确)同步的
HashMap
,同步应确保从更新它的线程以外的另一个线程查看时 modCount
不会过时。再说一遍,没有功能上的好处。对于不受线程限制且未正确同步的
HashMap
,您做错了,并且您需要担心的问题1比“快速失败”检测并发修改不是立即的更大。所以好处是......边际。与上述相反的是,将
modCount
声明为 volatile
will 对于所有读取或写入该内容的 HashMap
操作会产生性能损失(以内存屏障和额外内存读写的形式)场地。 (这是其中的大多数。)
总而言之:与性能开销相比,收益为零或最小,在某些用例中可能会很大。
1 - 例如,heisenbug
HashMap
损坏。