J'ai pris un coup d'oeil dans OpenJDK code source de l' CopyOnWriteArrayList
, et il semble que toutes les opérations d'écriture sont protégés par la même serrure et les opérations de lecture ne sont pas protégés à tous. Ce que je comprends, en vertu de JMM tous les accès à une variable (à la fois en lecture et en écriture) doivent être protégés par un verrou ou la réorganisation peut se produire des effets.
Par exemple, set(int, E)
méthode contient ces lignes (sous clé):
/* 1 */ int len = elements.length;
/* 2 */ Object[] newElements = Arrays.copyOf(elements, len);
/* 3 */ newElements[index] = element;
/* 4 */ setArray(newElements);
L' get(int)
méthode, d'autre part, seulement return get(getArray(), index);
.
Dans ma compréhension de JMM, cela signifie qu' get
peut observer le tableau dans un état incohérent si les énoncés 1 à 4 sont réorganisées comme 1-2(nouveau)-4-2(copyOf)-3.
Dois-je comprendre JMM de manière incorrecte ou est-il d'autres explications sur pourquoi est - CopyOnWriteArrayList
est thread-safe?