Я посмотрел на Исходный код 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
является поточно-ориентированным?