摘要:我們都接觸這些集合類,這些在包的集合類就都是快速失敗的而包下的類都是安全失敗,比如。安全失敗明白了什么是快速失敗之后,安全失敗也是非常好理解的。最后說明一下,快速失敗和安全失敗是對迭代器而言的。
什么是快速失敗(fail-fast)和安全失敗(fail-safe)?它們又和什么內容有關系。以上兩點就是這篇文章的內容,廢話不多話,正文請慢用。
我們都接觸 HashMap、ArrayList 這些集合類,這些在 java.util 包的集合類就都是快速失敗的;而 java.util.concurrent 包下的類都是安全失敗,比如:ConcurrentHashMap。
1. 快速失敗(fail-fast)在使用迭代器對集合對象進行遍歷的時候,如果 A 線程正在對集合進行遍歷,此時 B 線程對集合進行修改(增加、刪除、修改),或者 A 線程在遍歷過程中對集合進行修改,都會導致 A 線程拋出 ConcurrentModificationException 異常。
具體效果我們看下代碼:
HashMap hashMap = new HashMap(); hashMap.put("不只Java-1", 1); hashMap.put("不只Java-2", 2); hashMap.put("不只Java-3", 3); Set set = hashMap.entrySet(); Iterator iterator = set.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); hashMap.put("下次循環會拋異常", 4); System.out.println("此時 hashMap 長度為" + hashMap.size()); }
執行后的效果如下圖:
為什么在用迭代器遍歷時,修改集合就會拋異常時?
原因是迭代器在遍歷時直接訪問集合中的內容,并且在遍歷過程中使用一個 modCount 變量。集合在被遍歷期間如果內容發生變化,就會改變 modCount 的值。
每當迭代器使用 hashNext()/next() 遍歷下一個元素之前,都會檢測 modCount 變量是否為 expectedModCount 值,是的話就返回遍歷;否則拋出異常,終止遍歷。
2. 安全失?。╢ail-safe)明白了什么是快速失敗之后,安全失敗也是非常好理解的。
采用安全失敗機制的集合容器,在遍歷時不是直接在集合內容上訪問的,而是先復制原有集合內容,在拷貝的集合上進行遍歷。
由于迭代時是對原集合的拷貝進行遍歷,所以在遍歷過程中對原集合所作的修改并不能被迭代器檢測到,故不會拋 ConcurrentModificationException 異常
我們上代碼看下是不是這樣
ConcurrentHashMap concurrentHashMap = new ConcurrentHashMap(); concurrentHashMap.put("不只Java-1", 1); concurrentHashMap.put("不只Java-2", 2); concurrentHashMap.put("不只Java-3", 3); Set set = concurrentHashMap.entrySet(); Iterator iterator = set.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); concurrentHashMap.put("下次循環正常執行", 4); } System.out.println("程序結束");
運行效果如下,的確不會拋異常,程序正常執行。
最后說明一下,快速失敗和安全失敗是對迭代器而言的。并發環境下建議使用 java.util.concurrent 包下的容器類,除非沒有修改操作。
我是七淅 (xī),后臺回復「Java」,送你 13 本 Java 經典電子書。公眾號專注分享 Java 干貨、讀書筆記、成長思考。
參考文章:
https://blog.csdn.net/qq_3178...
如果你喜歡本文,歡迎來微信公眾號「不只Java」和我一起學(wan)習(shua)。后臺回復「Java」,送你 13 本 Java 經典電子書。公眾號專注分享 Java 干貨、讀書筆記、成長思考
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/72105.html
摘要:什么是線程餓死,什么是活鎖多線程中的忙循環是什么變量是什么變量和變量有什么不同類型變量提供什么保證能使得一個非原子操作變成原子操作嗎 JVM專題 showImg(https://segmentfault.com/img/remote/1460000019943435); (面試題+答案領取方式見個人主頁) Java 類加載過程? 描述一下 JVM 加載 Class 文件的原理機制? ...
摘要:第二天相同的時間相同的地方,我卻走錯了地方,原來成都騰訊大廈有兩棟。 在一個雨蒙蒙的清晨,百般無聊的閑逛中,突然回憶起了我這一生中的第一次面試經歷。雖然結果是以失敗而告終,但此時此刻的回憶,帶給我的并不是失敗而是成長。 作為一名實習生,我深刻的感受到在校園與社會夾縫中生活的不易。也十分的幸運,我還有足夠的青春與活力驅動著我去學習,讓我的未來不再遙不可及;讓我能在社會的這份土壤里扎根成長...
摘要:第二天相同的時間相同的地方,我卻走錯了地方,原來成都騰訊大廈有兩棟。 在一個雨蒙蒙的清晨,百般無聊的閑逛中,突然回憶起了我這一生中的第一次面試經歷。雖然結果是以失敗而告終,但此時此刻的回憶,帶給我的并不是失敗而是成長。 作為一名實習生,我深刻的感受到在校園與社會夾縫中生活的不易。也十分的幸運,我還有足夠的青春與活力驅動著我去學習,讓我的未來不再遙不可及;讓我能在社會的這份土壤里扎根成長...
摘要:第二天相同的時間相同的地方,我卻走錯了地方,原來成都騰訊大廈有兩棟。 在一個雨蒙蒙的清晨,百般無聊的閑逛中,突然回憶起了我這一生中的第一次面試經歷。雖然結果是以失敗而告終,但此時此刻的回憶,帶給我的并不是失敗而是成長。 作為一名實習生,我深刻的感受到在校園與社會夾縫中生活的不易。也十分的幸運,我還有足夠的青春與活力驅動著我去學習,讓我的未來不再遙不可及;讓我能在社會的這份土壤里扎根成長...
閱讀 2732·2021-11-11 17:21
閱讀 622·2021-09-23 11:22
閱讀 3587·2019-08-30 15:55
閱讀 1649·2019-08-29 17:15
閱讀 581·2019-08-29 16:38
閱讀 916·2019-08-26 11:54
閱讀 2516·2019-08-26 11:53
閱讀 2762·2019-08-26 10:31