gpt4 book ai didi

java - 为什么 ArrayList 从多个线程修改时不抛出 ConcurrentModificationException?

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:34:19 25 4
gpt4 key购买 nike

ConcurrentModificationException :当检测到对象的并发修改是不允许的时,方法可能会抛出此异常。

以上是 javadoc 中的 ConcurrentModificationException 定义。

所以我尝试测试下面的代码:

final List<String> tickets = new ArrayList<String>(100000);
for (int i = 0; i < 100000; i++) {
tickets.add("ticket NO," + i);
}
for (int i = 0; i < 10; i++) {
Thread salethread = new Thread() {
public void run() {
while (tickets.size() > 0) {
tickets.remove(0);
System.out.println(Thread.currentThread().getId()+"Remove 0");
}
}
};
salethread.start();
}

代码很简单。10 个线程从 arraylist 对象中删除元素。肯定是多个线程访问一个对象。但它运行正常。不会抛出异常。为什么?

最佳答案

我引用了 ArrayList 的大部分内容Javadoc 为了您的利益。解释您所看到的行为的相关部分已突出显示。

Note that this implementation is not synchronized. If multiple threads access an ArrayList instance concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more elements, or explicitly resizes the backing array; merely setting the value of an element is not a structural modification.) This is typically accomplished by synchronizing on some object that naturally encapsulates the list. If no such object exists, the list should be "wrapped" using the Collections.synchronizedList method. This is best done at creation time, to prevent accidental unsynchronized access to the list:

List list = Collections.synchronizedList(new ArrayList(...));

The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.

Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.

如果您在通过其迭代器访问它时在结构上修改列表,ArrayLists 通常会抛出并发修改异常(但这也不是绝对保证)。请注意,在您的示例中,您直接从列表中删除元素,并且没有使用迭代器。

如果您觉得有趣,您还可以浏览 ArrayList.remove 的实现, 以更好地了解其工作原理。

关于java - 为什么 ArrayList 从多个线程修改时不抛出 ConcurrentModificationException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14948971/

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