CopyOnWriteArrayList抛出CurrentModificationException
当我遍历列表时,我偶尔会得到一个ConcurrentModificationException
。 谷歌搜索告诉我,这可能是因为我在迭代它时在另一个线程中改变该列表并且为了使这个问题消失我应该使用java.util.concurrent.CopyOnWriteArrayList
….
……除了我已经是。
显然,我正在做一些非常愚蠢的事情。
有没有人知道如何诱使CopyOnWriteArrayList
抛出ConcurrentModificationException
? 如果重要,我正在使用Java 5。
编辑:由于我正在使用的mutators可能很重要,我正在以两种方式修改此列表:
- 在前面添加元素。 (
list.add(0, newElement);
) - 使用subList让旧项目脱落。 (
list = list.subList(0, MAX_LIST_SIZE);
)
那些举起红旗吗? 如果是这样,为什么? 我的理解是,因为这些操作首先复制了这个东西,所以任何现有的迭代器都会指向未经修改的原始文件,因此不关心。 我的知识是否有漏洞?
编辑2:导致问题的确切代码仍然有点模糊,但我至少可以发布我看到的exception:
java.util.ConcurrentModificationException at java.util.concurrent.CopyOnWriteArrayList$COWSubList.checkForComodification(Unknown Source) at java.util.concurrent.CopyOnWriteArrayList$COWSubList.iterator(Unknown Source) at....
…它指向我的代码中的for-each循环实例化。
那个COWSubList
似乎暗示我对subList
调用是我问题的根源; 我还是想明白为什么。
编辑3: * facepalm *
CopyOnWriteArrayList.subList()
返回List
, 而不是 CopyOnWriteArrayList
。 它返回的清单没有提供任何COWAL保护的隐含义务。 这使得使用像这样的subList()
来删除一个非常不好的想法。
不确定这是否是我的罪魁祸首,但它是可疑的,无论如何都需要纠正。
如果包含列表从其下面更改,则CopyOnWriteArrayList.subLists抛出ConcurrentModificationExceptions:
public class ListTest { private static List intList; public static void main (String[] args) { CopyOnWriteArrayList cowal = new CopyOnWriteArrayList (); cowal.add(1); cowal.add(2); cowal.add(3); List sub = cowal.subList(1, 2); cowal.add(4); sub.get(0); //throws ConcurrentModificationException } }
Sbodd有正确的答案,但听起来像使用CopyOnWriteArrayList而不是ArrayList只是试图掩盖错误。 真正的问题是尝试在迭代它时修改基础列表。 您需要在代码中找到您正在访问它的位置,并删除该用法或解决它。