CopyOnWriteArrayList抛出CurrentModificationException [英] CopyOnWriteArrayList throwing CurrentModificationException

查看:636
本文介绍了CopyOnWriteArrayList抛出CurrentModificationException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我遍历列表时,我偶尔会得到 ConcurrentModificationException 。一个Google搜索通知我,这可能是因为我改变了另一个线程中的列表,而迭代它,使这个问题消失我应该使用 java.util.concurrent.CopyOnWriteArrayList ....



...显然,



任何人都可以深入了解如何诱导 CopyOnWriteArrayList 抛出 ConcurrentModificationException ?如果重要,我使用Java 5。



编辑:由于我使用的mutator可能很重要,列表有两种方式:



  • 在前面添加元素。 ( list.add(0,newElement);

  • 使用subList让旧项目从后面脱落。 ( list = list.subList(0,MAX_LIST_SIZE);



那些红旗?如果是,为什么?我的理解是,因为这些操作首先创建事物的副本,任何现有的迭代器将指向未修改的原始,因此不在乎。我在我的知识中有洞吗?



编辑2:导致问题的确切代码仍然有点模糊,但我可以至少发布我看到的异常:

  
java.util.ConcurrentModificationException
at java.util.concurrent.CopyOnWriteArrayList $ COWSubList。 (未知来源)
at $ java.util.concurrent.CopyOnWriteArrayList $ COWSubList.iterator(未知来源)
at ....



...在我的代码中指向一个for-each循环实例化。



COWSubList 似乎暗示我调用 subList 是我的问题的根源;我仍然想了解为什么。



编辑3: * facepalm *



CopyOnWriteArrayList.subList()返回列表 a CopyOnWriteArrayList 。它返回的列表没有隐含的义务提供任何COWAL的保护。这使得使用 subList()像这样去除一个非常糟糕的主意。



解决方案

CopyOnWriteArrayList.subLists抛出ConcurrentModificationExceptions如果包含列表从下面更改:

  public class ListTest {

private static List< int [] > intList;

public static void main(String [] args){
CopyOnWriteArrayList< Integer> cowal = new CopyOnWriteArrayList< Integer>();
cowal.add(1);
cowal.add(2);
cowal.add(3);

List< Integer> sub = cowal.subList(1,2);
cowal.add(4);
sub.get(0); // throws ConcurrentModificationException
}
}


I'm occasionally getting a ConcurrentModificationException when I iterate over a list. A Google search informs me that it's probably because I'm altering that list in another thread while iterating over it and that to make this problem go away I should use java.util.concurrent.CopyOnWriteArrayList....

... except I already am.

Apparently, I'm doing something really stupid somewhere.

Does anybody have any insight into how one might induce CopyOnWriteArrayList to toss a ConcurrentModificationException? If it matters, I'm using Java 5.

Edit: Since the mutators I'm using may matter, I'm modifying this list in two ways:

  • Adding elements to the front. (list.add(0, newElement);)
  • Using subList to let older items fall off the back. (list = list.subList(0, MAX_LIST_SIZE);)

Do those raise red flags? If so, why? My understanding was that because these operations make a copy of the thing first, any existing iterators would be pointing at the unmodified original and would thus not care. Do I have a hole in my knowledge?

Edit 2: The precise code that's causing the problem is still a bit murky, but I can at least post the exception I'm seeing:


java.util.ConcurrentModificationException
    at java.util.concurrent.CopyOnWriteArrayList$COWSubList.checkForComodification(Unknown Source)
    at java.util.concurrent.CopyOnWriteArrayList$COWSubList.iterator(Unknown Source)
    at....

... where it points to a for-each loop instantiation in my code.

That COWSubList does seem to imply that my call to subList is the root of my problem; I'd still like to understand why.

Edit 3: *facepalm*

CopyOnWriteArrayList.subList() returns a List, not a CopyOnWriteArrayList. The list it returns is under no implied obligation to provide any of COWAL's protections. Which makes using subList() like this to remove elements a Very Bad Idea.

Don't know for certain if this is my culprit, but it's damned suspicious and needs to be corrected regardless.

解决方案

CopyOnWriteArrayList.subLists throw ConcurrentModificationExceptions if the containing list changes out from underneath it:

public class ListTest {

  private static List<int[]> intList;

  public static void main (String[] args) {
    CopyOnWriteArrayList<Integer> cowal = new CopyOnWriteArrayList<Integer>();
    cowal.add(1);
    cowal.add(2);
    cowal.add(3);

    List<Integer> sub = cowal.subList(1, 2);
    cowal.add(4);
    sub.get(0); //throws ConcurrentModificationException
  }
}

这篇关于CopyOnWriteArrayList抛出CurrentModificationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆