yo estaba tomando un vistazo al código fuente para WeakHashMap
y me encontré con este:¿Debería sincronizar en una ReferenceQueue?
private final ReferenceQueue<Object> queue = new ReferenceQueue<>();
private void expungeStaleEntries() {
for (Object x; (x = queue.poll()) != null;) {
synchronized (queue) {
/* snip */
}
}
}
¿Por qué este método sincronización en los ReferenceQueue
? WeakHashMap
en sí mismo no asegura que es seguro para hilos:
Como la mayoría de las clases de colección, esta clase no está sincronizada. Se puede construir un WeakHashMap sincronizado utilizando el método Collections.synchronizedMap.
Lo que me llevó a pensar que este detalle de implementación es que, de alguna manera, garantizar la seguridad hilo de la ReferenceQueue
sí (ya que la GC se modificarlo desde su propia Thread
). Sin embargo, the documentation for ReferenceQueue
no menciona nada acerca de las preocupaciones de concurrencia, y echando un vistazo al código fuente ReferenceQueue
revela que ni siquiera se sincroniza consigo mismo (usa un bloqueo interno).
¿Por qué WeakHashMap
se está sincronizando en su ReferenceQueue
? ¿Debo sincronizar en un ReferenceQueue
cada vez que lo uso?
+1 Buen hallazgo - Interesante cómo un método de lectura puede modificar el mapa. –
@andersoj Ahh, ese informe de errores lo deja en claro. Dado que llamar 'size' en' WeakHashMap' podría modificar el mapa subyacente, un usuario que simultáneamente llame 'size' en uno podría corromperlo inadvertidamente. Este comportamiento es contrario a la mayoría (¿todas?) De otras implementaciones JDK 'Map' que permitirían que varios hilos lean sus contenidos sin problemas, por lo que decidieron hacer que la clase fuera un poco segura para mantener la coherencia con' Especificación del mapa – Jeffrey
@John Vint, por ejemplo, LinkedHashMap get modifica el mapa porque almacena el pedido de acceso – gstackoverflow