He estado buscando el problema de escribir un Multimap concurrente, y tengo una implementación respaldada por el Google Guava AbstractSetMultimap y un mapa informático MapMaker que crea a demanda los conjuntos de valores como un conjunto ver sobre un ConcurrentHashMap. Con un poco de cuidado sobre las colecciones de vistas y varias envolturas, creo que esto se acerca bastante.implementando eliminar en un ConcurrentMultimap sin carreras
El gran problema, que ya ha sido discussed por others que have intentaron esto, parece ser que la eliminación de los valores-colecciones desde el mapa subyacente cuando se convierten en vacío, sin introducir condiciones de carrera.
Parece que existen un par de opciones.
- Deje las colecciones vacías allí. Esto filtrará algunos CHM, pero creo que al menos es correcto.
- intente de manera optimista eliminar la colección cuando esté vacía y compensar si aparece algo más en ella. Esto está lleno de razas y parece intrínsecamente imposible de arreglar.
- sincronizar todo en la colección de valores, que al menos permitiría esta eliminación, pero a costa de cualquier concurrencia después de la búsqueda inicial por clave.
- para una multa menor (tal vez, dependiendo de los patrones de uso?), Tal vez sincronizar en la creación y eliminación de colecciones de valores, es necesario verificar si eso cubre todo.
Preguntas:
- ¿Alguien sabe de cualquier aplicación mejor que esto? ¿Podemos componer mejor fragmentos de MapMaker, o necesita un ConcurrentHashMultimap especializado escrito desde cero?
- Si es difícil mejorar mucho en esto, ¿es probable que esta fuga sea un gran problema en la práctica? Las colecciones notables como java.util.HashMap, juc.ConcurrentHashMap y ArrayDeque no cambian el tamaño del almacén de respaldo hacia abajo, y ArrayList no lo hace automáticamente. Mientras limpiemos los objetos, me pregunto si esto importará demasiado.
Gracias
Editar: véase también the discussion here en la lista de correo de guayaba.
Edición 2: desde entonces he escrito esto. Por favor, consulte this Google code area para una implementación. Agradecería cualquier comentario de cualquier persona que lo intente, allí en lugar de aquí.
La forma en que resolví el comportamiento de Live View fue que 'multimap.get (" foo ")' devuelve un 'ForwardingSet' que delega al real. Por lo tanto, cada operación en ese conjunto busca la parte inferior, que puede cambiar entre dos llamadas. Esta indirección maneja la mayoría de los problemas allí, creo, pero hace que se cree una colección de valores espurios en cada operación en una clave no presente. Gracias por tus comentarios. –