首頁技術(shù)文章正文

fail-fast產(chǎn)生的原因是什么?解決辦法有哪些?

更新時(shí)間:2023-09-19 來源:黑馬程序員 瀏覽量:

IT培訓(xùn)班

fail-fast產(chǎn)生的原因就在于程序在對(duì)collection進(jìn)行迭代時(shí),某個(gè)線程對(duì)該collection在結(jié)構(gòu)上對(duì)其做了修改,這時(shí)迭代器就會(huì)拋出。

ConcurrentModificationException異常信息,從而產(chǎn)生fail-fast。要了解fail-fast機(jī)制,我們首先要對(duì)ConcurrentModificationException異常有所了解。當(dāng)方法檢測(cè)到對(duì)象的并發(fā)修改,但不允許這種修改時(shí)就拋出該異常。

同時(shí)需要注意的是,該異常不會(huì)始終指出對(duì)象已經(jīng)由不同線程并發(fā)修改,如果單線程違反了規(guī)則,同樣也有可能會(huì)拋出改異常。

誠(chéng)然,迭代器的快速失敗行為無法得到保證,它不能保證一定會(huì)出現(xiàn)該錯(cuò)誤,但是快速失敗操作會(huì)盡大努力拋出ConcurrentModificationException異常,所以因此,為提高此類操作的正確性而編寫一個(gè)依賴于此異常的程序是錯(cuò)誤的做法,正確做法是:ConcurrentModificationException應(yīng)該僅用于檢測(cè)bug。

fail-fast解決辦法這里有兩種解決方案:

方案一:在遍歷過程中所有涉及到改變modCount值得地方全部加上synchronized或者直接使用Collections.synchronizedList,這樣就可以解決。但是不推薦,因?yàn)樵鰟h造成的同步鎖可能會(huì)阻塞遍歷操作。

方案二:使用CopyOnWriteArrayList來替換ArrayList。推薦使用該方案。CopyOnWriteArrayList為何物?ArrayList的一個(gè)線程安全的變體,其中所有可變操作(add、set等等)都是通過對(duì)底層數(shù)組進(jìn)行一次新的復(fù)制來實(shí)現(xiàn)的。該類產(chǎn)生的開銷比較大,但是在兩種情況下,它非常適合使用。1:在不能或不想進(jìn)行同步遍歷,但又需要從并發(fā)線程中排除沖突時(shí)。2:當(dāng)遍歷操作的數(shù)量大大超過可變操作的數(shù)量時(shí)。遇到這兩種情況使用CopyOnWriteArrayList來替代

分享到:
在線咨詢 我要報(bào)名
和我們?cè)诰€交談!