resueltos principiantes para hilos fuente entre ejemplos comunicacion codigo java multithreading

principiantes - Asignación de referencia atómica multi-hilo de Java



hilos en java pdf (4)

¿Qué pasa con las colecciones CopyOnWrite ...?

java.util.concurrent.CopyOnWriteArraySet java.util.concurrent.CopyOnWriteArraySet and org.apache.mina.util.CopyOnWriteMap

Pueden ser una buena combinación en su caso y son seguros para subprocesos.

Tengo un caché que implementé usando un simple HashMap. me gusta -

HashMap<String,String> cache = new HashMap<String,String>();

Este caché se usa la mayor parte del tiempo para leer valores de él. Tengo otro método que recarga la memoria caché y dentro de este método básicamente creo una nueva memoria caché y luego asigno la referencia. Según entiendo, la asignación de referencia de objeto es Atomic 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 el caché como volátil, otros subprocesos no podrán ver los cambios, pero no es un momento crítico para mi caso de uso propagar el cambio en el caché a otros subprocesos y pueden continuar trabajando con el antiguo. por tiempo extendido

¿Ves algún problema con el enhebrado? Tenga en cuenta que muchos subprocesos se leen desde la memoria caché y solo a veces se vuelve a cargar la memoria caché.

EDITAR - ¿Mi principal confusión es que no tengo que usar la referencia a la Atomic aquí ya que la operación de asignación en sí es atómica?

EDITAR: entiendo que para que el pedido sea correcto, debo marcar el caché como volátil. Pero si el método refreshCache está marcado como sincronizado, no tengo que hacer que el caché sea volátil, ya que el bloque sincronizado se encargará de ordenar y la visibilidad.


Deberías marcar el caché como volatile .

Si bien observa que otros subprocesos pueden continuar usando un caché obsoleto durante "mucho tiempo", debe tener en cuenta que, sin un borde de sincronización, es probable que sigan usando el caché obsoleto para siempre. Probablemente ese no sea el comportamiento deseado.

En orden de preferencia (principalmente debido a la legibilidad):

  • Actualizar el campo en un método sincronizado.
  • Use AtomicReference<Map<>>
  • Usar volatile

Véase también esta question .


No es seguro sin una barrera de memoria adecuada.

Uno pensaría que la asignación de caché (cache = newCache) ocurriría después de los pasos para completar el caché. Sin embargo, otros subprocesos pueden sufrir la reordenación de estas declaraciones para que la asignación parezca suceder antes de llenar la memoria caché. Por lo tanto, es posible capturar la nueva memoria caché antes de que esté completamente construida o, peor aún, ver una excepción de modificación concurrente.

Debe hacer cumplir la relación suceso-antes para evitar que se vuelva a ordenar y declarar que la memoria caché es volátil.


Parece estar bien. Asegúrese de que refreshCache no se llame con demasiada frecuencia o marque como synchronized .