gpt4 book ai didi

java - CopyOnWriteArrayList 如何是线程安全的?

转载 作者:IT老高 更新时间:2023-10-28 20:26:59 26 4
gpt4 key购买 nike

我查看了 OpenJDK source codeCopyOnWriteArrayList似乎所有的写操作都受到同一个锁的保护,而读操作根本不 protected 。据我了解,在 JMM 下,对变量的所有访问(读取和写入)都应该受到锁的保护,否则可能会发生重新排序的影响。

例如,set(int, E) 方法包含这些行(处于锁定状态):

/* 1 */ int len = elements.length;
/* 2 */ Object[] newElements = Arrays.copyOf(elements, len);
/* 3 */ newElements[index] = element;
/* 4 */ setArray(newElements);

另一方面,get(int) 方法只执行 return get(getArray(), index);

在我对 JMM 的理解中,这意味着如果语句 1-4 像 1-2(new)-4-2(copyOf) 一样重新排序,get 可能会观察到数组处于不一致状态 - 3.

我是否对 JMM 理解有误,或者是否有任何其他解释说明为什么 CopyOnWriteArrayList 是线程安全的?

最佳答案

如果您查看底层数组引用,您会看到它被标记为 volatile。当发生写入操作时(例如在上面的摘录中),此 volatile 引用仅在最终语句中通过 setArray 更新。到目前为止,任何读取操作都会从数组的旧副本返回元素。

重要的一点是数组更新是原子操作,因此读取将始终看到数组处于一致状态。

只为写入操作锁定的优点是提高了读取的吞吐量:这是因为 CopyOnWriteArrayList 的写入操作可能会非常慢,因为它们涉及复制整个列表。

关于java - CopyOnWriteArrayList 如何是线程安全的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2950871/

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