【发布时间】:2021-11-28 22:29:06
【问题描述】:
有一个列表同时被两个线程排序和迭代。正如预期的那样,它导致ConcurrentModificationException。目前尚不清楚错误发生的时间。
import java.util.stream.*;
import java.util.*;
public class Confusionist {
static List<Integer> numbers;
public static void main(String args[]) {
numbers = IntStream.generate(() -> java.util.concurrent.ThreadLocalRandom.current().nextInt()).limit(100).boxed().collect(Collectors.toList());
new Thread(new Accessor()).start();
new Thread(new Accessor()).start();
}
static class Accessor implements Runnable{
public void run(){
String threadName = Thread.currentThread().getName();
char threadDenoter = threadName.charAt(threadName.length()-1);
System.out.printf("Thread: %s, Going to sort\n", threadName);
Collections.sort(numbers, Integer::compareTo);
Iterator<Integer> iterator = numbers.iterator();
System.out.printf("Thread: %s, Going to iterate\n", threadName);
while(iterator.hasNext()){
iterator.next();
System.out.printf("%c", threadDenoter);
}
}
}
}
输出:(出现几次)
Thread: Thread-0, Going to sort
Thread: Thread-1, Going to sort
Thread: Thread-0, Going to iterate
0000000000000000000000000000000000000000000000000000000000000000000000000000000Exception in thread "Thread-0" java.util.ConcurrentModificationException
at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013)
at java.base/java.util.ArrayList$Itr.next(ArrayList.java:967)
at HelloCodiva$Accessor.run(HelloCodiva.java:21)
at java.base/java.lang.Thread.run(Thread.java:831)
000000Thread: Thread-1, Going to iterate
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
Completed with exit code: 0
两个线程都对同一个列表进行了排序,它们已经获得了一个迭代器并且它们已经开始迭代。 (打印 0 和 1)。
当一个线程完成迭代时(这里线程 1 完成迭代,它已经打印了 100 个 1),另一个迭代失败。
- 为什么第一个线程完成后另一个线程的迭代失败?
- 当两个线程分别完成排序和获取迭代器时,底层迭代器不会改变。为什么这会导致现阶段出现异常?
【问题讨论】:
标签: java multithreading iterator