ArrayList?foreach循環(huán)增添刪除導(dǎo)致ConcurrentModificationException解決分析
一、使用背景
在阿里巴巴開發(fā)手冊中,有這樣一條規(guī)定:不要在foreach循環(huán)里進行add和remove操作(這里指的是List的add和remove操作),
否則會拋出ConcurrentModificationException。remove元素請使用iterator。

二、源碼
1.我們知道foreach是語法糖,他本質(zhì)還是iterator進行的循環(huán),因此下面的代碼和使用foreach循環(huán)是一樣的。
在循環(huán)里面我們使用“錯誤”操作,使用List的add方法進行操作,會拋出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的值賦值給一個變量expectedModCount,其中modcount表示List實際被增刪的次數(shù),expectedModCount表示該迭代器期望被增刪的次數(shù),當(dāng)新建Itr類的時候會給他賦初始值,只有通過該迭代器進行值的增刪才會修改該值


2.iterator.next();
①在調(diào)用迭代器的next方法時,他會進行檢查,比較modCount和expectedModCount的值,如果不相等,Concurrent


總結(jié)
1.modCount和expectedModeCount不一致才會拋出ConcurrentModificationException。當(dāng)我們調(diào)用List的remove方法時,他只會修改modCount的值;當(dāng)我們調(diào)用iterator的remove方法,他會將modCount的值賦值給expectedModeCount
2.modCount和expectedModeCount是屬于fast-fail機制,用于多線程中,當(dāng)進行遍歷的時候,有其他線程修改值的時候就會進行檢查
解決方法
- 1.使用普通for循環(huán)進行操作
- 2.在循環(huán)中使用iterator進行操作
- 3.使用stream流進行過濾
- 4.使用fast-saft安全的類,如ConCurrentLinkedQueue
以上就是ArrayList foreach循環(huán)增添刪除導(dǎo)致ConcurrentModificationException解決分析的詳細(xì)內(nèi)容,更多關(guān)于ArrayList foreach循環(huán)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JAVA實現(xiàn)連接本地打印機并打印文件的實現(xiàn)代碼
這篇文章主要介紹了JAVA實現(xiàn)連接本地打印機并打印文件的實現(xiàn)代碼,需要的朋友可以參考下2019-10-10
spring boot使用RabbitMQ實現(xiàn)topic 主題
本篇文章主要介紹了spring boot使用RabbitMQ實現(xiàn)topic 主題,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03
教你使用idea搭建ssm詳細(xì)教程(Spring+Spring Mvc+Mybatis)
今天教大家使用idea搭建ssm詳細(xì)教程(Spring+Spring Mvc+Mybatis),文中有非常詳細(xì)的圖文介紹及代碼示例,對正在學(xué)習(xí)使用idea的小伙伴很有幫助,需要的朋友可以參考下2021-05-05

