Я рассмотрел исходный код 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 (новый) -4-2 (copyOf) -3.
Я правильно понимаю JMM или есть другие объяснения, почему CopyOnWriteArrayList
является потокобезопасным?