gpt4 book ai didi

java - 使用多线程将元素添加到 ArrayList 时,有时会给出 ConcurrentModificationException 有时不会?

转载 作者:行者123 更新时间:2023-12-04 10:54:55 31 4
gpt4 key购买 nike

我尝试迭代 ArrayList使用多线程的对象,但有时它会给出 ConcurrentModificationException有时不是?我无法理解这里发生了什么。

我在下面分享我的代码:

import java.util.ArrayList;
import java.util.Iterator;

public class ConcurrentDemo extends Thread{
static ArrayList l=new ArrayList();
public void run()
{
/*
* try { Thread.sleep(2000); } catch(InterruptedException e) { }
*/
System.out.println("child thread updating list");
l.add("D");
System.out.println(l);

}

public static void main(String args[]) throws InterruptedException
{
l.add("A");
l.add("B");
l.add("c");
ConcurrentDemo c=new ConcurrentDemo();
c.start();
System.out.println(l);
Iterator itr =l.iterator();
while(itr.hasNext())
{
String s1=(String)itr.next();
System.out.println("main thread list:" + s1);
Thread.sleep(3000);
}
System.out.println(l);
}
}

最佳答案

请看我的回答内联 在您的代码中:

import java.util.ArrayList;
import java.util.Iterator;

public class ConcurrentDemo extends Thread{
static ArrayList l=new ArrayList();
public void run()
{

System.out.println("child thread updating list");
l.add("D");
System.out.println(l);

}

public static void main(String args[]) throws InterruptedException
{

//----> Main thread starts here
l.add("A");
l.add("B");
l.add("c");

//----> l now contains A,B,C

ConcurrentDemo c=new ConcurrentDemo();

//----> You have started a second thread here
c.start();

//-----> Its not determined, which line will be executed first from now on, as 2 threads are running parallelly, the ConcurrentModificationException most likely occur in cases, when the "l.add("D");" called within the "run();" method AFTER the Iterator has been created.

System.out.println(l);
Iterator itr =l.iterator();
while(itr.hasNext())
{
String s1=(String)itr.next();
System.out.println("main thread list:" + s1);
Thread.sleep(3000);
}
System.out.println(l);
}
}

请注意,关于迭代器,如果在迭代过程中以任何方式修改底层集合,而不是通过调用迭代器接口(interface)上的适当方法,则迭代器的行为是未指定的。 Reference

Instead of randomly failing when you do this, the collection is nice enough to keep track of how many times it's been modified, and throw ConcurrentModificationException when it detects concurrent modification. Reference



如果您计划通过添加新元素来修改迭代器的底层集合,请考虑使用 ListIterator

您的代码示例:
  static ArrayList l=new ArrayList();
ListIterator listItr =l.listIterator();
listItr.add(e);

欲了解更多信息,请查看 Java Concurrency and Multithreading tutorial .

编辑:
由于可能很难注意到,我在上面的代码中突出显示了最重要的内联注释:

在您调用 c.start(); 之后它不确定,首先执行哪一行,因为 2 个线程并行运行,ConcurrentModificationException 最有可能发生在以下情况下,当 l.add("D");run(); 内调用方法 之后 迭代器已创建。

关于java - 使用多线程将元素添加到 ArrayList 时,有时会给出 ConcurrentModificationException 有时不会?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59265410/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com