gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 09:04:22 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) 方法仅返回 get(getArray(), index);

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

我对 JMM 的理解是否错误,或者对于为什么 CopyOnWriteArrayList 是线程安全的还有其他解释吗?

最佳答案

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

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

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

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

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