2012-05-14 9 views
10

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?

Respuesta

6

Si observa ReferenceQueue verá que admite explícitamente el enhebrado dentro de la plataforma, porque establece que el método remove() se bloqueará hasta que haya una nueva entrada disponible.

La synchronized que ve en WeakHashMap consiste en garantizar que los subprocesos múltiples que acceden a ReferenceQueue estén sincronizados correctamente.

Puede que le interese este bug at bugs.sun.com interesante.

Para responder a su pregunta, creo que la sincronización externa del ReferenceQueue no es necesaria si se asegura de que solo se accede por un único hilo. No utilizaría (y no puedo pensar en una buena razón) para usar un solo ReferenceQueue como consumidor de múltiples hilos.

+0

+1 Buen hallazgo - Interesante cómo un método de lectura puede modificar el mapa. –

+1

@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

+0

@John Vint, por ejemplo, LinkedHashMap get modifica el mapa porque almacena el pedido de acceso – gstackoverflow

Cuestiones relacionadas