ConcurrentModificationException併發修改異常
ConcurrentModificationException併發修改異常
#ConcurrentModificationException
在學習List集合的時候,在遍歷的時候修改元素,發現報了錯誤。
List<String> l=new ArrayList<String>();
l.add("北京");
l.add("南京");
l.add("東京");
Iterator<String> it=l.iterator();
while(it.hasNext()){
String ss=it.next();
if(ss.equals("南京"))
{
l.add("上海");
}
System.out.println(ss);
}
報錯
Exception in thread “main” java.util.ConcurrentModificationException
at java.util.ArrayList
I
t
r
.
c
h
e
c
k
F
o
r
C
o
m
o
d
i
f
i
c
a
t
i
o
n
(
A
r
r
a
y
L
i
s
t
.
j
a
v
a
:
909
)
a
t
j
a
v
a
.
u
t
i
l
.
A
r
r
a
y
L
i
s
t
Itr.checkForComodification(ArrayList.java:909) at java.util.ArrayList
Itr.checkForComodification(ArrayList.java:909)atjava.util.ArrayListItr.next(ArrayList.java:859)
at com.neu.test4.ListDemo.main(ListDemo.java:32)
原因就出在32行上的next方法出了問題,集合的迭代器是不允許在遍歷的時候對集合集合進行操作的。
我們來看看API是怎麼說的
看原始碼:因為我們的集合l是ArrayList的物件,且使用了裡面的add()方法和Iterator方法。
public boolean add(E e) {
modCount++;//5、而我們在操作時,實際修改次數會變化,但是預期修改次數不會變化。這就讓我們在checkForComodification方法裡比較兩個值的時候不同,就會丟擲併發修改異常。
//而我們的modCount這個值來自於ArrayList,但是我們檢視ArrayList卻沒有,那是因為ArrayList繼承了AbstractList這個抽下類,而抽象類裡面就有這個值。如下
add(e, elementData, size);
return true;
}
protected transient int modCount = 0;//6、AbstractList裡面的。一開始值為0,然後在呼叫next,會判斷,可是我們在next方法裡做了用了add方法,而add方法會修改modCount的值。造成異常。
public Iterator<E> iterator() {
return new Itr();
}
Iterator有返回了一個Itr物件。(在報錯裡面也可以看到)看next方法。
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;//4、而在Itr類裡面,已經將實際修改次數賦值給了期望修改次數。
@SuppressWarnings("unchecked")
public E next() {//1、在進入next方法時,會呼叫checkForComodification方法。如下
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
final void checkForComodification() {
if (modCount != expectedModCount)//2、而這個方法首先會比較兩個值:modCount(實際修改集合的次數)和expectedModCount(預期修改集合的次數)。
throw new ConcurrentModificationException();//3、判斷,如果這兩個值不相等,就會丟擲我們所看到的ConcurrentModificationException異常。
}
解決辦法
可以用for迴圈遍歷集合呀。哈哈哈哈,這樣就不會報錯了。
相關文章
- 併發修改異常 ConcurrentModificationException詳解Exception
- bag系列ConcurrentModificationException---併發修改異常Exception
- HashMap中ConcurrentModificationException異常解讀HashMapException
- 【高併發】由InterruptedException異常引發的思考Exception
- Laravel 修改 dingo 異常處理LaravelGo
- 併發相關的現象和異常(Phenomena AND Anomalies)
- api模式下修改異常類ExceptionAPI模式Exception
- python自定義異常,使用raise引發異常PythonAI
- Laravel 修改驗證異常的響應格式Laravel
- 如何解決jquery.jsonp在併發下容易發生異常的bugjQueryJSON
- Java併發(五)執行緒池使用番外-分析RejectedExecutionException異常Java執行緒Exception
- InterruptedException異常會對併發程式設計產生哪些影響?Exception程式設計
- 如何修改監聽異常的優先順序
- 多執行緒下使用List中的subList和remove方法產生的 java.util.ConcurrentModificationException 異常執行緒REMJavaException
- 異常和異常呼叫鏈
- 異常篇——異常記錄
- 異常篇——異常處理
- 【Spring Cloud】Feign呼叫異常觸發降級後如何捕獲異常SpringCloud
- Golang常見的併發模式Golang模式
- 異常-異常的注意事項
- Java 異常(二) 自定義異常Java
- 如何避免ConcurrentModificationExceptionException
- 異常-編譯期異常和執行期異常的區別編譯
- 異常?
- 異常
- 異常處理:IDEA Git 修改後的檔案無法CommitIdeaGitMIT
- MySQL:MGR修改max_binlog_cache_size引數導致異常MySql
- 異常-異常的概述和分類
- 異常-throws的方式處理異常
- hibernate異常之--count查詢異常
- 兩種異常(CPU異常、使用者模擬異常)的收集
- jmu-Java-06異常-01-常見異常Java
- 併發王者課-青銅9:防患未然-如何處理執行緒中的異常執行緒
- go 併發程式設計案例二 常見併發模型介紹Go程式設計模型
- Java 異常表與異常處理原理Java
- restframework 異常處理及自定義異常RESTFramework
- java.util.ConcurrentModificationExceptionJavaException
- 迭代器的 ConcurrentModificationExceptionException