He utilizado LinkedHashMap
con accessOrder
cierto junto con permitir un máximo de 500 entradas en cualquier momento como la memoria caché LRU para datos. Pero debido a problemas de escalabilidad, quiero pasar a una alternativa segura para subprocesos. ConcurrentHashMap
parece bueno en ese sentido, pero carece de las características de accessOrder
y removeEldestEntry(Map.Entry e)
que se encuentran en LinkedHashMap
. ¿Alguien puede señalar algún enlace o ayudarme a facilitar la implementación?¿Cómo implementar ConcurrentHashMap con características similares en LinkedHashMap?
Respuesta
Hice algo similar recientemente con ConcurrentHashMap<String,CacheEntry>
, donde CacheEntry ajusta el elemento actual y agrega estadísticas de desalojo de caché: tiempo de expiración, tiempo de inserción (para expulsión FIFO/LIFO), último tiempo utilizado (para desalojo LRU/MRU), número de visitas (para desalojo LFU/MFU), etc. El desalojo real se sincroniza y crea un ArrayList<CacheEntry>
y realiza un Collections.sort() en él utilizando el Comparador apropiado para la estrategia de desalojo . Dado que esto es costoso, cada desalojo se corta en el 5% inferior de las entradas de caché. Sin embargo, estoy seguro de que la optimización del rendimiento ayudaría.
En su caso, ya que está haciendo FIFO, puede mantener un ConcurrentLinkedQueue por separado. Cuando agrega un objeto a ConcurrentHashMap, realice un ConcurrentLinkedQueue.add() de ese objeto. Cuando desee desalojar una entrada, haga una Simulación ConcurrentLinkedQueue.poll() para eliminar el objeto más antiguo, luego también elimínelo de ConcurrentHashMap.
Actualización: Otras posibilidades en esta área incluyen una Java Collections synchronization wrapper y Java 1.6 ConcurrentSkipListMap.
Tu sugerencia parece mucho a la que necesito. Significa que tengo algunos gastos generales para mantener otros elementos que consumirán el mismo tamaño que el del conjunto del mapa. De todos modos, esto está bien para mí. – DKSRathore
Sé que ha pasado un tiempo pero encontré su respuesta y ¿podría decirme cuándo recibió ArrayList
Envuelva el mapa en Collections.synchronizedMap()
. Si necesita llamar a métodos adicionales, entonces synchronize
en el mapa que obtuvo de esta llamada, e invoque el método original en el mapa original (see the javadocs for an example). Lo mismo aplica cuando itera sobre las claves, etc.
Aaron esto empeorará mis problemas de escalabilidad. Dado que la actualización del mapa se convertiría en serial. ConcurrentHashMap tiene una función para que más de uno pueda actualizar el mapa al mismo tiempo. – DKSRathore
ConcHM tiene algunas propiedades específicas que no se asignan fácilmente a LinkedHM (es decir, permite insertarse simultáneamente siempre que el hash no se asocie a la misma clave de segmento). Esta optimización no es posible cuando necesita mantener el orden de inserción. Debe decidir cuál es más importante para usted. –
¿Ha intentado utilizar una de las muchas soluciones de almacenamiento en caché como ehcache? Puede intentar usar LinkedHashMap con un ReadWriteLock. Esto le daría acceso de lectura concurrente.
Aún no. Pero EHcache sería mi otra alternativa. – DKSRathore
Menciona que desea resolver problemas de escalabilidad con una alternativa "segura para subprocesos". "Seguridad de subprocesos" aquí significa que la estructura es tolerante de intentos de acceso simultáneo, en el sentido de que no sufrirá daños por el uso simultáneo sin sincronización externa. Sin embargo, tal tolerancia no necesariamente ayuda a mejorar la "escalabilidad". En el enfoque más simple, aunque generalmente erróneo, intentará sincronizar su estructura internamente y aún así dejar las operaciones no atómicas check-then-act inseguras.
Las memorias caché LRU requieren al menos cierto conocimiento de la estructura total. Necesitan algo como el recuento de los miembros o el tamaño de los miembros para decidir cuándo expulsar, y luego deben poder coordinar el desalojo con intentos simultáneos de leer, agregar o eliminar elementos. Intentar reducir la sincronización necesaria para el acceso simultáneo a la estructura "principal" combate contra su mecanismo de desalojo, y obliga a que su política de desalojo sea menos precisa en sus garantías.
La respuesta actualmente aceptada menciona "cuando desea desalojar una entrada". Ahí radica el problema. ¿Cómo sabes cuándo quieres desalojar una entrada? ¿Qué otras operaciones necesita detener para tomar esta decisión?
Echa un vistazo http://code.google.com/p/concurrentlinkedhashmap/.
Esto puede parecer viejo ahora, pero al menos solo para mi propio historial de seguimiento, voy a agregar mi solución aquí: Combiné ConcurrentHashMap que mapea K-> subclase de WeakReference, ConcurrentLinkedQueue, y una interfaz que define la deserialización de los objetos de valor basados en K para ejecutar el almacenamiento en memoria caché LRU correctamente. La cola contiene refs fuertes, y el GC desalojará los valores de la memoria cuando sea apropiado. El seguimiento del tamaño de la cola involucró a AtomicInteger, ya que no se puede inspeccionar realmente la cola para determinar cuándo expulsar. El caché manejará el desalojo de/agregar a la cola, así como la administración del mapa. Si el GC desalojó el valor de la memoria, la implementación de la interfaz de deserialización manejará la recuperación del valor. También tuve otra implementación que involucraba spooling en disco/relectura de lo que estaba en la cola, pero eso fue mucho más lento que la solución que publiqué aquí, ya que tenía que sincronizar spooling/reading.
Gracias, es bueno agregar su solución a una publicación, incluso cuando – Guillaume
- 1. ¿Cómo construir e implementar continuamente ramas de características con Maven?
- 2. ¿Cómo puedo implementar filigranas similares a Stack Overflow en formularios?
- 3. ¿Hay algún inconveniente con ConcurrentHashMap?
- 4. ConcurrentHashMap parámetros de constructor?
- 5. Recomendaciones para crear un nuevo sitio web con características similares a "aplicaciones" en .NET
- 6. Cómo implementar teclas de acceso rápido similares a gmail
- 7. Shrink LinkedHashMap en Java
- 8. ConcurrentHashMap en Java?
- 9. Ordenando LinkedHashMap
- 10. ConcurrentHashMap bloqueo
- 11. LinkedHashMap en .NET
- 12. Implementando un LinkedHashMap concurrente
- 13. LinkedHashMap firma
- 14. ConcurrentHashMap y Hashtable en Java
- 15. Una poderosa herramienta de administración para MySQL con características similares a SQL Server Management studio
- 16. Java ConcurrentHashMap no es seguro ... ¿con wth?
- 17. Sobrecarga de memoria ConcurrentHashMap
- 18. Equivalente para LinkedHashMap en Python
- 19. ConcurrentHashMap para C++
- 20. ConcurrentHashMap vs sincronizada HashMap
- 21. ConcurrentHashMap poner vs putIfAbsent
- 22. Volatile HashMap vs ConcurrentHashMap
- 23. ConcurrentHashMap instrucciones de reorden?
- 24. Cómo iterar a través de LinkedHashMap con listas como valores
- 25. ¿Existe algún marco web o proyecto que proporcione características similares a "Muro"
- 26. ¿Cómo comparar XML similares con PHPUnit?
- 27. LinkedHashMap ¿LIFO o FIFO?
- 28. Características del lenguaje para implementar el álgebra relacional
- 29. Mercurial: ¿funciona con colas similares a estantes?
- 30. ¿Cómo obtengo un keyIterator para un LinkedHashMap?
Este es un problema realmente difícil. Hemos intentado abordarlo en google-collections y aún no estamos del todo allí. Pero seremos ... –
Pregunta similar: http://stackoverflow.com/questions/1391918/does-java-have-a-linkedconcurrenthashmap-data-structure – Vadzim