來源:blog.csdn.net/dabusiGin/article/details/105483426 錯誤的結論 在網上搜索HashMap中變數modCount的作用時,大部分的解釋都是這樣: Fail-Fast 機制 我們知道 java.util.HashMap 不是線程安全的,因此如果在使用 ...
來源:blog.csdn.net/dabusiGin/article/details/105483426
錯誤的結論
在網上搜索HashMap中變數modCount的作用時,大部分的解釋都是這樣:
Fail-Fast 機制
我們知道 java.util.HashMap
不是線程安全的,因此如果在使用迭代器的過程中有其他線程修改了map,那麼將拋出ConcurrentModificationException
,這就是所謂fail-fast
策略。
這一策略在源碼中的實現是通過 modCount
域,modCount
顧名思義就是修改次數,對HashMap 內容的修改都將增加這個值,那麼在迭代器初始化過程中會將這個值賦給迭代器的 expectedModCount
。在迭代過程中,判斷 modCount
跟 expectedModCount
是否相等,如果不相等就表示已經有其他線程修改了 Map:註意到 modCount 聲明為 volatile,保證線程之間修改的可見性。
這個解釋有放在JDK5和JDK6的時候,也許是正確的,因為在JDK5和JDK6中變數modCount確實聲明為volatile。但在JDK7和JDK8中,已經沒有這樣聲明瞭!!!!!
下麵是JDK5、JDK6、JDK7和JDK8的源碼:
1.JDK5源碼截圖
2.JDK6源碼截圖
3.JDK7源碼截圖
4.JDK8源碼截圖
我的思考
難道到了JDK7和JDK8中就不需要使用modCount變數,防止使用迭代器的過程中有其他線程修改了map?????
我的思考是這樣的:註意看變數modCount的註釋中讓我們See ConcurrentModificationException
,那麼我們就找到ConcurrentModificationException
異常,在該異常的註釋中,有這樣一段描述。
Note that this exception does not always indicate that an object has
been concurrently modified by a <i>different</i> thread. If a single
thread issues a sequence of method invocations that violates the
contract of an object, the object may throw this exception. For
example, if a thread modifies a collection directly while it is
iterating over the collection with a fail-fast iterator, the iterator
will throw this exception.
大致翻譯如下:
請註意,此異常並不總是表示對象已被其他線程同時修改。如果單個線程發出一系列違反對象約定的方法調用,則該對象可能會拋出此異常。例如,如果線程使用有fail-fast機制的迭代器在集合上迭代時修改了集合,迭代器將拋出此異常。
通過這段對ConcurrentModificationException
異常的描述,我有以下看法:
- 該異常不單單會在多線程情況下發生;
- 在單線程情況下也可能發生,就是在有使用有fail-fast機制的迭代器遍歷集合時,有修改集合的操作也會拋出此異常;
- HashMap中的modCount是為了結論2而設計的。
近期熱文推薦:
1.1,000+ 道 Java面試題及答案整理(2022最新版)
4.別再寫滿屏的爆爆爆炸類了,試試裝飾器模式,這才是優雅的方式!!
覺得不錯,別忘了隨手點贊+轉發哦!