gpt4 book ai didi

java - ArrayList 中的异常示例?

转载 作者:行者123 更新时间:2023-12-02 05:36:07 25 4
gpt4 key购买 nike

我正在使用 ArrayList,并且我想要一个异常示例,以防多个线程尝试在不同步的情况下访问同一列表?我在单线程应用程序中完成了此操作,其中如果我们在迭代时从列表中删除一个元素,它会抛出 ConcurrentModificationExceptoin 但我想在多线程环境中实现相同的效果。如果有人能给我一个例子,我将不胜感激?

package com.test2;

public class ThreadTest extends Thread {

List list = new ArrayList<String>();

@Override
public void run() {

list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
list.add("6");
list.add("7");
list.add("8");

Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}

}

public static void main(String[] args) {



Thread th1 = new ThreadTest();
Thread th2 = new ThreadTest();
Thread th3 = new ThreadTest();
th1.start();
th2.start();
th3.start();
try {
th1.join();
th2.join();
th3.join();
} catch (InterruptedException e) {
e.printStackTrace();
}




}

}

最佳答案

您正在每个线程中访问一个单独的列表实例。由于每个列表仅由一个线程访问,因此您不会出现并发错误。

List list = new ArrayList<String>();

声明一个实例字段。因此,每次调用 new ThreadTest() 都会创建一个新列表。为了使所有 ThreadTest 实例使用相同的列表,请尝试将字段设为静态(即类字段):

static List list = new ArrayList<String>();

至于如何会发生错误,请查看 the code for ArrayList's add method :

 public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}

如果两个线程同时调用add,它们可以同时处理elementData[size++] = e语句。 The size field is not declared volatile ;因此,两个线程最终可能会写入 elementData 数组中的相同索引。

即使size被声明为 volatile size++操作也不是原子的。请参阅 How to model a situation, when i++ is corrupted by simultaneously executing threads? 有关 size++ 之类的操作如何在多线程环境中失败的示例。

最后,如果您不明白 volatile 和原子在 Java 上下文中的含义,那么在编写任何多线程代码之前,您确实需要阅读有关 Java 并发编程的内容。这将是一项值得的投资,因为通过了解这些概念,您可以避免很多麻烦。

关于java - ArrayList 中的异常示例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24947530/

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