快速失败(fail-fast)和安全失败(fail-safe)
我們都接觸 HashMap、ArrayList 這些集合類,這些在 java.util 包的集合類就都是快速失敗的;而 java.util.concurrent 包下的類都是安全失敗,比如:ConcurrentHashMap。
1. 快速失敗(fail-fast)
在使用迭代器對集合對象進行遍歷的時候,如果 A 線程正在對集合進行遍歷,此時 B 線程對集合進行修改(增加、刪除、修改),或者 A 線程在遍歷過程中對集合進行修改,都會導致 A 線程拋出 ConcurrentModificationException 異常。
具體效果我們看下代碼:
為什么在用迭代器遍歷時,修改集合就會拋異常時?
原因是迭代器在遍歷時直接訪問集合中的內容,并且在遍歷過程中使用一個 modCount 變量。集合在被遍歷期間如果內容發生變化,就會改變 modCount 的值。每當迭代器使用 hashNext()/next() 遍歷下一個元素之前,都會檢測 modCount 變量是否為 expectedModCount 值,是的話就返回遍歷;否則拋出異常,終止遍歷。
2. 安全失敗(fail-safe)
明白了什么是快速失敗之后,安全失敗也是非常好理解的。
采用安全失敗機制的集合容器,在遍歷時不是直接在集合內容上訪問的,而是先復制原有集合內容,在拷貝的集合上進行遍歷。 由于迭代時是對原集合的拷貝進行遍歷,所以在遍歷過程中對原集合所作的修改并不能被迭代器檢測到,故不會拋 ConcurrentModificationException 異常
我們上代碼看下是不是這樣
最后說明一下,快速失敗和安全失敗是對迭代器而言的。并發環境下建議使用 java.util.concurrent 包下的容器類,除非沒有修改操作。
文章轉自:https://juejin.im/post/5be62527f265da617369cdc8
總結
以上是生活随笔為你收集整理的快速失败(fail-fast)和安全失败(fail-safe)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring IOC 核心流程浓缩
- 下一篇: 多图长文 | 聊聊C端转型B端产品那些事