我查看了OpenJDK 的源代码,CopyOnWriteArrayList
似乎所有的写操作都受到同一个锁的保护,而读操作根本不受保护。据我了解,在 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 的理解,这意味着get
如果语句 1-4 像 1-2(new)-4-2(copyOf)-3 一样重新排序,则可能会观察到数组处于不一致状态。
我是否错误地理解了 JMM,或者是否有任何其他解释为什么CopyOnWriteArrayList
是线程安全的?