Tengo un caché que implementé usando un HashMap de simeple. como -Asignación de referencia atómica multihilo de Java
HashMap<String,String> cache = new HashMap<String,String>();
Este caché se usa la mayor parte del tiempo para leer los valores del mismo. Tengo otro método que recarga el caché y, dentro de este método, básicamente creo un nuevo caché y luego le asigno la referencia. Como entiendo, la asignación de referencia de objeto es Atómica en Java.
public class myClass {
private HashMap<String,String> cache = null;
public void init() {
refreshCache();
}
// this method can be called occasionally to update the cache.
public void refreshCache() {
HashMap<String,String> newcache = new HashMap<String,String>();
// code to fill up the new cache
// and then finally
cache = newcache; //assign the old cache to the new one in Atomic way
}
}
Entiendo que si no declaro caché tan volátil, otros hilos no serán capaces de ver los cambios, pero no es momento crítico para mi caso de uso para propagar el cambio en la caché de otros hilos y se puede seguir trabajando con la memoria caché anterior durante un tiempo prolongado.
¿Ve algún problema de enhebrado? Tenga en cuenta que muchos subprocesos están leyendo desde la memoria caché y solo a veces la memoria caché se vuelve a cargar.
EDIT Mi principal confusión es que no tengo que usar AtomicReference aquí ya que la operación de asignación en sí es atómica?
EDITAR - Entiendo que para hacer el pedido correcto, debería marcar el caché como volátil. Pero si el método refreshCache está marcado como sincronizado, no es necesario que la memoria caché sea volátil, ya que el bloque sincronizado se ocupará tanto de ordenar como de la visibilidad.
para un simple uso del almacenamiento en caché, generalmente uso un * ConcurrentHashMap * y no me preocupo por el bloqueo. Normalmente no me importa si un cálculo (referencialmente transparente) ocurre dos veces (digamos porque el hilo B comienza a calcular el mismo valor que el hilo A está actualmente calculando y, por lo tanto, aún no ha puesto en el caché). En tu caso, también haría que * cache * sea * volátil *. Pero no veo el sentido de "actualizar el caché". Convierta su caché en una LRU/MRU y simplemente agregue un nuevo valor almacenado en caché en lugar de "restablecerlo". – SyntaxT3rr0r
Al menos refrescar la caché usando un nuevo mapa permite el uso de una implementación de mapa de caché sin bloqueo – ThomasRS