ArrayList?foreach循環(huán)增添刪除導(dǎo)致ConcurrentModificationException解決分析
一、使用背景
在阿里巴巴開發(fā)手冊(cè)中,有這樣一條規(guī)定:不要在foreach循環(huán)里進(jìn)行add和remove操作(這里指的是List的add和remove操作),
否則會(huì)拋出ConcurrentModificationException。remove元素請(qǐng)使用iterator。
二、源碼
1.我們知道foreach是語法糖,他本質(zhì)還是iterator進(jìn)行的循環(huán),因此下面的代碼和使用foreach循環(huán)是一樣的。
在循環(huán)里面我們使用“錯(cuò)誤”操作,使用List的add方法進(jìn)行操作,會(huì)拋出ConcurrentModificationException
ArrayList<String> arrayList = new ArrayList<>(); arrayList.add("apple"); Iterator<String> iterator = arrayList.iterator(); while(iterator.hasNext()){ String value = iterator.next(); if("apple".equals(value)){ arrayList.add("orange"); } }
三、源碼解析
1.arrayList.iterator();
①返回Itr類,并將modcount的值賦值給一個(gè)變量expectedModCount,其中modcount表示List實(shí)際被增刪的次數(shù),expectedModCount表示該迭代器期望被增刪的次數(shù),當(dāng)新建Itr類的時(shí)候會(huì)給他賦初始值,只有通過該迭代器進(jìn)行值的增刪才會(huì)修改該值
2.iterator.next();
①在調(diào)用迭代器的next方法時(shí),他會(huì)進(jìn)行檢查,比較modCount和expectedModCount的值,如果不相等,Concurrent
總結(jié)
1.modCount和expectedModeCount不一致才會(huì)拋出ConcurrentModificationException。當(dāng)我們調(diào)用List的remove方法時(shí),他只會(huì)修改modCount的值;當(dāng)我們調(diào)用iterator的remove方法,他會(huì)將modCount的值賦值給expectedModeCount
2.modCount和expectedModeCount是屬于fast-fail機(jī)制,用于多線程中,當(dāng)進(jìn)行遍歷的時(shí)候,有其他線程修改值的時(shí)候就會(huì)進(jìn)行檢查
解決方法
- 1.使用普通for循環(huán)進(jìn)行操作
- 2.在循環(huán)中使用iterator進(jìn)行操作
- 3.使用stream流進(jìn)行過濾
- 4.使用fast-saft安全的類,如ConCurrentLinkedQueue
以上就是ArrayList foreach循環(huán)增添刪除導(dǎo)致ConcurrentModificationException解決分析的詳細(xì)內(nèi)容,更多關(guān)于ArrayList foreach循環(huán)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringMVC中RequestContextHolder獲取請(qǐng)求信息的方法
這篇文章主要介紹了SpringMVC中RequestContextHolder獲取請(qǐng)求信息的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04Java中-Xms和-Xmx參數(shù)的使用與默認(rèn)內(nèi)存設(shè)置
在 Java 程序運(yùn)行時(shí),內(nèi)存的管理是影響程序性能的關(guān)鍵因素之一,Java 程序使用的內(nèi)存主要由兩部分組成:堆內(nèi)存和棧內(nèi)存,Java 提供了多個(gè)參數(shù)來控制堆內(nèi)存的大小,其中最常用的參數(shù)是 -Xms 和 -Xmx,本文將詳細(xì)介紹這些參數(shù),需要的朋友可以參考下2024-11-11EL調(diào)用Java方法_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
簡單來說,我們?cè)谝粋€(gè)類中的某個(gè)方法,可以使用EL進(jìn)行調(diào)用,這個(gè)能被EL表達(dá)式調(diào)用的方法稱之為EL函數(shù),但是這種方式必須滿足兩點(diǎn)要求,具體哪兩點(diǎn),大家可以參考下本文2017-07-07