thread method example blocks java concurrency synchronization jvm java-memory-model

method - synchronized object java



Java happend before thread start (3)

De acuerdo con la documentación: ExecuterService javadocs

Efectos de coherencia de memoria: las acciones en un subproceso antes del envío de una tarea ejecutable o invocable a un ExecutorService suceden, antes de cualquier acción realizada por esa tarea, que a su vez sucede, antes de que el resultado se recupere a través de Future.get ().

Esto significa que su concepto es correcto.

Leí en alguna parte que comenzar un hilo tiene un efecto especial en la relación happend before. Ahora no estoy seguro de si mi código garantiza la relación antes de la relación, así que por favor ilumíname.

Tengo un hilo Dispatcher y una clase Worker implementando la interfaz Runnable . El hilo Dispatcher crea una nueva instancia del Worker y llena una LinkedList en la instancia Worker a través del método add con elementos.

Luego, el despachador entrega la instancia Worker a ExecutorService través del método de execute .

Luego, el método de ejecución en la clase Trabajador comienza a acceder y eliminar elementos de LinkedList .

¿La instancia del Worker recién iniciada ve el mismo estado de LinkedList que el Dispatcher? ¿O podría ser que LinkedList está en algún estado inconsciente? ¿Tendré que completar LinkedList en un método sincronizado?


La especificación del lenguaje Java escribe :

Una acción que inicia un hilo se sincroniza, con la primera acción en el hilo que comienza.

Si una acción x sincroniza, con una acción siguiente y , también tenemos hb(x, y) .

Si tenemos dos acciones y , escribimos hb(x, y) para indicar que x sucede, antes de y .

Sin embargo, según su descripción, no está claro si eso es relevante en su caso, ya que usted habla de un ejecutor, pero no explica cuándo se crea ese ejecutor o cuándo se iniciaron sus hilos de trabajo.

Lo que es relevante es el siguiente extracto de JavaDoc del Ejecutor :

Efectos de coherencia de memoria: las acciones en un hilo antes de enviar un objeto Runnable a un Executor suceden, antes de que comience su ejecución, quizás en otro hilo.

Por lo tanto, su código es seguro, siempre que la Runnable distribución ya no Runnable acceso a la lista después de enviar Runnable .


Si hay bloqueo u otras primitivas de sincronización utilizadas, y solo está utilizando una lista ArrayList antigua, entonces los dos hilos podrían ver diferentes estados.

Al coordinar el trabajo entre dos subprocesos separados, debe utilizar una estructura de datos simultánea segura para subprocesos o usar un código de sincronización para garantizar una "instantánea de memoria" consistente entre los subprocesos.

Una de las razones por las que esto es importante se debe al almacenamiento en caché. Los dos hilos, que se ejecutan simultáneamente en diferentes procesadores, podrían haber guardado en caché algunos objetos en diferentes registros locales (que son locales para esos procesadores).