Estoy buscando en la implementación de ConcurrentHashMap y algo me hace confundirme.ConcurrentHashMap instrucciones de reorden?
/* Specialized implementations of map methods */
V get(Object key, int hash) {
if (count != 0) { // read-volatile
HashEntry<K,V> e = getFirst(hash);
while (e != null) {
if (e.hash == hash && key.equals(e.key)) {
V v = e.value;
if (v != null)
return v;
return readValueUnderLock(e); // recheck
}
e = e.next;
}
}
return null;
}
y
/**
* Reads value field of an entry under lock. Called if value
* field ever appears to be null. This is possible only if a
* compiler happens to reorder a HashEntry initialization with
* its table assignment, which is legal under memory model
* but is not known to ever occur.
*/
V readValueUnderLock(HashEntry<K,V> e) {
lock();
try {
return e.value;
} finally {
unlock();
}
}
y constructor HashEntry
/**
* ConcurrentHashMap list entry. Note that this is never exported
* out as a user-visible Map.Entry.
*
* Because the value field is volatile, not final, it is legal wrt
* the Java Memory Model for an unsynchronized reader to see null
* instead of initial value when read via a data race. Although a
* reordering leading to this is not likely to ever actually
* occur, the Segment.readValueUnderLock method is used as a
* backup in case a null (pre-initialized) value is ever seen in
* an unsynchronized access method.
*/
static final class HashEntry<K,V> {
final K key;
final int hash;
volatile V value;
final HashEntry<K,V> next;
HashEntry(K key, int hash, HashEntry<K,V> next, V value) {
this.key = key;
this.hash = hash;
this.next = next;
this.value = value;
}
poner en práctica
tab[index] = new HashEntry<K,V>(key, hash, first, value);
confundí al comentario HashEntry, como JSR-133, una vez HashEntry es const ructed, todos los campos finales serán visibles para todos los demás hilos, valor campo es volátil, por lo que creo que es visible para otros hilos también ??? . Otro punto es el reordenamiento que dijo: la referencia del objeto HashEntry se puede asignar a tabulación [...] antes de que esté completamente construida (por lo que el resultado es que otros subprocesos pueden ver esta entrada pero e.value puede ser nulo)?
Actualización: Leo this artículo y es bueno. Pero necesito para cuidar de un caso como este
ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue();
thread1:
Person p=new Person("name","student");
queue.offer(new Person());
thread2:
Person p = queue.poll();
¿Existe la posibilidad de que Thread2 recibir un objeto Persona sin terminar-construcción al igual que HashEntry en
pestaña [índice] = new HashEntry (clave , hash, primero, valor); ?
Con valor volátil que puede garantizar la visibilidad de todos los otros hilos. – dimitrisli
sí, entonces todos los campos son visibles por todos los demás hilos, ¿por qué solo tenemos que preocuparnos de que el valor de 'valor' sea nulo? – secmask