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
- EBS Concurrent Manager(併發管理器)異常處理
- Laravel 修改 dingo 異常處理LaravelGo
- api模式下修改異常類ExceptionAPI模式Exception
- InterruptedException異常會對併發程式設計產生哪些影響?Exception程式設計
- EBS Concurrent Manager(併發管理器)異常處理[final]
- python自定義異常,使用raise引發異常PythonAI
- Laravel 修改驗證異常的響應格式Laravel
- 如何解決jquery.jsonp在併發下容易發生異常的bugjQueryJSON
- 修改pfile引數檔案過程的異常
- Java併發(五)執行緒池使用番外-分析RejectedExecutionException異常Java執行緒Exception
- Golang常見的併發模式Golang模式
- 異常篇——異常處理
- 異常和異常呼叫鏈
- getter,setter 直接修改造成的空指標異常指標
- Java 異常(二) 自定義異常Java
- Java checked異常和unchecked異常。Java
- 使用JDBCTemp.operate發生異常JDBC
- 異常-編譯期異常和執行期異常的區別編譯
- java併發面試常識之copyonwriteJava面試
- go 併發程式設計案例二 常見併發模型介紹Go程式設計模型
- 異常-throws的方式處理異常
- 異常處理與異常函式函式
- 多執行緒下使用List中的subList和remove方法產生的 java.util.ConcurrentModificationException 異常執行緒REMJavaException
- jmu-Java-06異常-01-常見異常Java
- 【Spring Cloud】Feign呼叫異常觸發降級後如何捕獲異常SpringCloud
- 併發王者課-青銅9:防患未然-如何處理執行緒中的異常執行緒
- Flask開發技巧之異常處理Flask
- Oracle開發基礎-異常處理Oracle
- [Java開發之路](5)異常詳解Java
- (轉)pl/sql開發異常處理SQL
- hibernate異常之--count查詢異常
- Java 異常表與異常處理原理Java
- restframework 異常處理及自定義異常RESTFramework
- java併發面試常識之ArrayBlockingQueueJava面試BloC