He echado un vistazo a OpenJDK source code de CopyOnWriteArrayList
y parece que todas las operaciones de escritura están protegidas por el mismo bloqueo y las operaciones de lectura no están protegidas en absoluto. Según tengo entendido, en JMM todos los accesos a una variable (tanto de lectura como de escritura) deben estar protegidos por bloqueo o pueden producirse nuevos efectos de reordenación.¿Cómo puede CopyOnWriteArrayList ser seguro para subprocesos?
Por ejemplo, set(int, E)
método contiene estas líneas (menores de bloqueo):
/* 1 */ int len = elements.length;
/* 2 */ Object[] newElements = Arrays.copyOf(elements, len);
/* 3 */ newElements[index] = element;
/* 4 */ setArray(newElements);
El método get(int)
, por otro lado, sólo hace return get(getArray(), index);
.
En mi comprensión de JMM, esto significa que get
puede observar la matriz en un estado incoherente si las instrucciones 1-4 se reordenan como 1-2 (nuevo) -4-2 (copyOf) -3.
¿Entiendo JMM incorrectamente o hay alguna otra explicación sobre por qué CopyOnWriteArrayList
es thread-safe?
Gracias. Me he perdido el hecho de que la matriz es 'volátil '. – Fixpoint
Un detalle importante es que volátil solo se aplica a la referencia de matriz en sí, no al contenido de la matriz. Sin embargo, dado que todos los cambios en la matriz se realizan ** antes ** de que se publique su referencia, las garantías volátiles se extienden al contenido de la matriz. – assylias