[英]Why i get ConcurrentModificationException even using an Iterator?
[英]Why I get ConcurrentModificationException even though I am using locks?
這是我的課:
public class AComplicatedclass {
private List<Connection> activeConnections;
private Lock lock = new ReentrantLock();
public void printConnections() {
lock.lock();
for(Connection c : activeConnections){ //exception happens here
...prints details about connection
activeConnections.remove(c);
}
lock.unlock();
}
private class MyThread extends TimerTask {
public void run() {
lock.lock();
...can alter activeConnections....
lock.unlock();
}
}
}
如您所見,鎖對象應防止由於並發訪問該共享陣列而引起的問題。 然而,當printConnections()
方法被調用時,我得到一個ConcurrentModificationException
在for
。
怎么會? 根本沒有並發修改!
您最有可能在for循環中修改您的集合。 作為有關ConcurrentModificationException狀態的文檔
例如,如果線程在使用快速失敗迭代器迭代集合時直接修改了集合,則迭代器將拋出此異常。
迭代器引發異常的原因是,無法再確定下一個要返回的元素。
所以,如果你想修改你的收藏,你需要或者切換到類似的CopyOnWriteArrayList或使用迭代器明確地作為
Iterator<Connection> iterator = activeConenctions.iterator();
while(iterator.hasNext()) {
Connection c = iterator.next();
if(/* what ever */) {
iterator.remove();
}
}
即使您的應用程序是單線程的,在foreach迭代期間編輯列表幾乎總是會導致ConcurrentModificationException。
如果您需要在迭代過程中刪除項目,請使用迭代器:
final Iterator<Connection> iterator = activeConnections.iterator();
while(iterator.hasNext()) {
final Connection connection = iterator.next();
// ...prints details about connection
iterator.remove();
}
根據ConcurrentModificationException
的Javadoc:
例如,通常不允許一個線程修改Collection而另一個線程對其進行迭代。 通常,在這些情況下,迭代的結果是不確定的。 如果檢測到此行為,則某些Iterator實現(包括JRE提供的所有通用集合實現的實現)可能會選擇拋出此異常。 執行此操作的迭代器稱為快速失敗迭代器,因為它們會快速干凈地失敗,而不是在未來的不確定時間內冒任意,不確定的行為的風險。
這與不同步的訪問無關。
有問題的操作的一些示例:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.