java - ¿HashMap simultáneo con claves débiles y hash de identidad?
concurrency weak-references (4)
¿Cómo obtengo un ConcurrentHashMap
con claves débiles y hashes de identidad en Java? Creo que las colecciones de guayabas de Google pueden ofrecer algo así, pero ¿puedo obtenerlo de la biblioteca estándar? ¿Qué otras opciones tengo?
Creo que las colecciones de guayabas de Google pueden ofrecer algo así, pero ¿puedo obtenerlo de la biblioteca estándar?
La respuesta corta a esta pregunta es No. Java SE no implementa esta combinación en particular.
Podría crear una instancia de un
java.util.concurrent.ConcurrentHashMap
con claves deWeakReference
, y hacer un trabajo adicional para implementar la eliminación de las entradas del mapa para las referencias rotas, pero eso no le dará semántica hash de identidad.Podría crear una instancia de
java.util.IdentityHashMap
conWeakReference
claves deWeakReference
y hacer un trabajo adicional para implementar la eliminación de las entradas del mapa para las referencias rotas, pero eso no le dará un comportamiento concurrente.El uso de un
java.util.WeakHashMap
no le dará tanto la concurrencia como el hash de identidad.Podría (en teoría) envolver la clase clave en algo que anule los métodos de
equals
naturales yhashcode
. Pero eso es más probable que sea inutilizable.No creo que sea posible hacerlo anulando los métodos en
ConcurrentHashMap
oIdentityHashMap
.
Tal vez la única opción viable sería cambiar las clases clave equals
y los métodos de hashcode
para estar basados en la identidad. Pero eso no funcionará para los tipos de clave "incorporados" (especialmente los final
) o para los casos en los que necesite valores / hashcode basados en valores en otras partes de la aplicación.
La implementación de Google Guava parece ser la forma más fácil de hacerlo. Uno puede inicializar el mapa requerido con el new MapMaker().weakKeys().makeMap()
y usarlo como lo haría con java.util.concurrent.ConcurrentHashMap
. Ver el apidoc para más detalles.
Si su aplicación está bajo Spring Framework (la versión es gt 3.2), puede considerar usar org.springframework.util.ConcurrentReferenceHashMap
. A continuación se muestra su descripción:
Un ConcurrentHashMap que usa referencias suaves o débiles tanto para claves como para valores. Esta clase se puede usar como una alternativa a Collections.synchronizedMap (new WeakHashMap> ()) con el fin de soportar un mejor rendimiento cuando se accede al mismo tiempo. Esta implementación sigue las mismas restricciones de diseño que ConcurrentHashMap, con la excepción de que se admiten valores nulos y claves nulas.
NOTA: El uso de referencias significa que no hay garantía de que los elementos colocados en el mapa estén disponibles posteriormente. El recolector de basura puede descartar referencias en cualquier momento, por lo que puede parecer que un subproceso desconocido está eliminando entradas silenciosamente.
Si no se especifica explícitamente, esta implementación utilizará referencias de entrada suave.
busque ConcurrentWeakIdentityHashMap, obtendrá muchos ejemplos. Yo mismo escribí un implemento, porque creo que el código hash de org / ehcache / core / internal / util / ConcurrentWeakIdentityHashMap $ WeakReference es tan malo.