大家好,這裡是IT技術百貨,專注於有價值的IT技術知識分享;
今天跟大家分享集合遍歷中的fail-fast和fail-safe的實現機制
fail-fast和fail-safe指的是什麼
fail-fast和fail-safe指的是利用iterator進行集合遍歷時,當集合被修改之後是否拋出異常;
fail-fast機制會拋出異常(ConcurrentModificationException),而fail-safe機制不會拋出異常;
下面截圖中的代碼默認是fail-fast機制,運行的話會拋出異常:
fail-safe機制:
具體是怎麼實現的?
fail-fast機制:
使用fail-fast機制的集合在內部維護了一個字段:modCount ,用來記錄這個集合被修改了多少次,比如:增刪元素、替換元素、排序等
Iterator迭代器在初始化的時候,會記錄下這個 modCount 這個字段值,如下圖所示:
在遍歷過程中next、remove、add方法會對這個值進行校驗,具體代碼如下:
特別說明:iterator內部的add和remove方法修改集合不會拋異常;iterator內部做了處理。
fail-safe機制:
fail-safe機制實現很簡單,就是將原來的集合copy一份,然後基於新拷貝的集合進行遍歷;
返回的Iterator實際上是COWIterator,通過源碼可以看出COWIterator持有對象的一份快照;
之後所有的遍歷都是基於這個快照進行的;
靈魂拷問,真的是拷貝了一份新的嗎?
通過代碼來看,是直接將CopyOnWriteArrayList對象的元素數組賦值給了Iterator,這就說明本質上還是用的一個對象,那為什麼不會失敗呢?
對比CopyOnWriteArrayList 和 ArrayList的源碼可以發現,CopyOnWriteArrayList的add和remvoe操作都是將原數組拷貝到一個新數組裡面,也就是不會改變原數組,而ArrayList事先聲明瞭一個大容量數組,當添加或者刪除操作時儘量在原數組上進行;
每週讀源碼:String類的equals是怎麼實現的(阿里面試手寫代碼)
感謝瀏覽閱讀,如果覺得內容有價值歡迎點贊,收藏,轉發;喜歡請關注“IT技術百貨”
關鍵字: 源碼 CopyOnWriteArrayList add