有人可以通过ConcurrentModificationException向我解释吗?

有人可以通过ConcurrentModificationException向我解释吗?,第1张

有人可以通过ConcurrentModificationException向我解释吗?

一般来说

ConcurrentModificationException
,如果您尝试在迭代集合修改集合,则会引发a。例如:

public class Main {    public static void main(String[] args)     throws Exception {        final List<Object> c1 = new ArrayList<Object>(Arrays.<Object>asList(1, 2, 3));        for (Object o: c1) c1.remove(o);    }}

java.util.ConcurrentModificationException
在运行时导致运行,因为我们在迭代列表时正在修改列表(注意:此处仅涉及单个线程)。列表的迭代器检测到此情况,并导致异常。

如果所需修改是从迭代器刚收到非常元素的缺失,就可以达到预期的效果(在单线程情况下!)通过与工作直接迭代。将

for
(每个)循环替换为:

final Iterator<Object> iterator = c1.iterator();while (iterator.hasNext()) {    final Object o = iterator.next();    if (satisfiesSomeCriterion(o)) iterator.remove();}

但是,这并不适用于所有修改。例如,添加将不起作用。以下代码仍然失败:

for (Object o: c1) c1.add(Integer.valueOf(((Integer)o).intValue() + 10));

如果基础集合是

List
,则可以使用a
ListIterator
代替普通的迭代器来解决此限制:

final ListIterator<Integer> iterator = c1.listIterator();while (iterator.hasNext()) {    final Integer o = iterator.next();    if (satisfiesSomeCriterion(o)) iterator.add(Integer.valueOf(o.intValue() + 10);}

但是请注意,这与上面给出的代码(插入元素的其他位置)不同。还要注意,这

ListIterator.add
是一个可选方法;一个实现可能
UnsupportedOperationException
在调用时抛出一个。

上述所有内容仅适用于单线程情况。如果您尝试在没有适当同步的情况下从多个线程同时访问同一集合,则会出现一系列新问题,因为这不仅可能导致

ConcurrentModificationException
迭代线程中出现s,而且可能破坏集合内部数据的完整性。结构。

您可以做几件事:

  • 使用并发感知集合(例如
    CopyOnWriteArrayList
    您已经提到的集合)
  • 通过
    Collections.synchronizedList
    ...Set
    ...Whatever
    )包装集合。但是请注意,在这种情况下,您仍然有责任针对迭代提供适当的锁定规则。有关详细信息,请参见此答案。
  • 在将原始集合传递给后台作业之前,先对其进行备份(并确保后台作业是使用该副本的唯一线程)
  • 通过
    synchronized
    块保护集合的所有使用(例如,将集合本身​​用作“监视”对象,尽管更好:使用专用的监视对象)。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5428867.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-11
下一篇 2022-12-11

发表评论

登录后才能评论

评论列表(0条)

保存