一、快速失?。╢ail—fast)
在用迭代器遍歷一個(gè)集合對(duì)象時(shí),如果遍歷過(guò)程中對(duì)集合對(duì)象的內(nèi)容進(jìn)行了修改(增加、刪除、修改),則會(huì)拋出 Concurrent Modification Exception。
原理:迭代器在遍歷時(shí)直接訪問集合中的內(nèi)容,并且在遍歷過(guò)程中使用一個(gè) modCount 變量。集合在被遍歷期間如果內(nèi)容發(fā)生變化,就會(huì)改變 modCount 的值。每當(dāng)?shù)魇褂?hashNext()/next() 遍歷下一個(gè)元素之前,都會(huì)檢測(cè) modCount 變量是否為 expectedmodCount 值,是的話就返回遍歷;否則拋出異常,終止遍歷。
注意:這里異常的拋出條件是檢測(cè)到 modCount != expectedmodCount 這個(gè)條件。如果集合發(fā)生變化時(shí)修改 modCount 值剛好又設(shè)置為了 expectedmodCount 值,則異常不會(huì)拋出。因此,不能依賴于這個(gè)異常是否拋出而進(jìn)行并發(fā)操作的編程,這個(gè)異常只建議用于檢測(cè)并發(fā)修改的 bug。
場(chǎng)景:java.util 包下的集合類都是快速失敗的,不能在多線程下發(fā)生并發(fā)修改(迭代過(guò)程中被修改)。
二、安全失?。╢ail—safe)
采用安全失敗機(jī)制的集合容器,在遍歷時(shí)不是直接在集合內(nèi)容上訪問的,而是先復(fù)制原有集合內(nèi)容,在拷貝的集合上進(jìn)行遍歷。
原理:由于迭代時(shí)是對(duì)原集合的拷貝進(jìn)行遍歷,所以在遍歷過(guò)程中對(duì)原集合所作的修改并不能被迭代器檢測(cè)到,所以不會(huì)觸發(fā) Concurrent Modification Exception。
>缺點(diǎn):基于拷貝內(nèi)容的優(yōu)點(diǎn)是避免了 Concurrent Modification Exception,但同樣地,迭代器并不能訪問到修改后的內(nèi)容,即:迭代器遍歷的是開始遍歷那一刻拿到的集合拷貝,在遍歷期間原集合發(fā)生的修改迭代器是不知道的。
場(chǎng)景:java.util.concurrent 包下的容器都是安全失敗,可以在多線程下并發(fā)使用,并發(fā)修改。
原文地址:http://www.cnblogs.com/ygj0930/p/6543350.html