ArrayList?foreach循環(huán)增添刪除導(dǎo)致ConcurrentModificationException解決分析
一、使用背景
在阿里巴巴開(kāi)發(fā)手冊(cè)中,有這樣一條規(guī)定:不要在foreach循環(huán)里進(jìn)行add和remove操作(這里指的是List的add和remove操作),
否則會(huì)拋出ConcurrentModificationException。remove元素請(qǐng)使用iterator。
二、源碼
1.我們知道foreach是語(yǔ)法糖,他本質(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類(lèi),并將modcount的值賦值給一個(gè)變量expectedModCount,其中modcount表示List實(shí)際被增刪的次數(shù),expectedModCount表示該迭代器期望被增刪的次數(shù),當(dāng)新建Itr類(lèi)的時(shí)候會(huì)給他賦初始值,只有通過(guò)該迭代器進(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)行過(guò)濾
- 4.使用fast-saft安全的類(lèi),如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)求信息的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04Spring Cloud Config解決的問(wèn)題和案例
Spring Cloud Config 是 Spring Cloud 套件中的一個(gè)工具,提供了在分布式系統(tǒng)中對(duì)外部化配置的服務(wù)器端和客戶端支持,本文介紹了Spring Cloud Config解決的問(wèn)題和案例,文中有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下2024-07-07Java中-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ù)來(lái)控制堆內(nèi)存的大小,其中最常用的參數(shù)是 -Xms 和 -Xmx,本文將詳細(xì)介紹這些參數(shù),需要的朋友可以參考下2024-11-11EL調(diào)用Java方法_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
簡(jiǎn)單來(lái)說(shuō),我們?cè)谝粋€(gè)類(lèi)中的某個(gè)方法,可以使用EL進(jìn)行調(diào)用,這個(gè)能被EL表達(dá)式調(diào)用的方法稱之為EL函數(shù),但是這種方式必須滿足兩點(diǎn)要求,具體哪兩點(diǎn),大家可以參考下本文2017-07-07如何解決springboot自動(dòng)重啟問(wèn)題
這篇文章主要介紹了如何解決springboot自動(dòng)重啟問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09