ventana una sencillo para juegos hechos hacer ejemplos crear como codigo bienvenida java multithreading

java - una - ¿Qué significa este código de unión de hilo?



jframe netbeans codigo (8)

En este código, ¿qué significan los dos une y rompe? t1.join() hace que t2 detenga hasta que termine t1 ?

Thread t1 = new Thread(new EventThread("e1")); t1.start(); Thread t2 = new Thread(new EventThread("e2")); t2.start(); while (true) { try { t1.join(); t2.join(); break; } catch (InterruptedException e) { e.printStackTrace(); } }


Cuando el hilo tA llama a tB.join (), sus causas no solo esperan que tB muera o tA se interrumpa a sí mismo, sino que crea una relación de pasada-antes entre el último enunciado en tB y el enunciado siguiente después de tB.join () en el hilo de tA.

Todas las acciones en un hilo ocurren, antes de que cualquier otro hilo vuelva exitosamente desde un join () en ese hilo.

Significa programa

class App { // shared, not synchronized variable = bad practice static int sharedVar = 0; public static void main(String[] args) throws Exception { Thread threadB = new Thread(() -> {sharedVar = 1;}); threadB.start(); threadB.join(); while (true) System.out.print(sharedVar); } }

Imprimir siempre

>> 1111111111111111111111111 ...

Pero el programa

class App { // shared, not synchronized variable = bad practice static int sharedVar = 0; public static void main(String[] args) throws Exception { Thread threadB = new Thread(() -> {sharedVar = 1;}); threadB.start(); // threadB.join(); COMMENT JOIN while (true) System.out.print(sharedVar); } }

Puede imprimir no solo

>> 0000000000 ... 000000111111111111111111111111 ...

Pero

>> 00000000000000000000000000000000000000000000 ...

Siempre solo ''0''.

Porque Java Memory Model no requiere ''transferir'' nuevo valor de ''sharedVar'' desde threadB a thread principal sin relación heppens-before (inicio de hilo, unión de subprocesos, uso de palabra clave ''synchonized'', uso de variables AtomicXXX, etc.).


Desde la página de documentación de Oracle en Joins

El método de join permite que un subproceso espere la finalización de otro.

Si t1 es un objeto Thread cuyo hilo se está ejecutando actualmente,

t1.join() : causes the current thread to pause execution until t1''s thread terminates.

Si t2 es un objeto Thread cuyo hilo se está ejecutando actualmente,

t2.join(); causes the current thread to pause execution until t2''s thread terminates.

join API es API de bajo nivel, que se ha introducido en versiones anteriores de java. Se han cambiado muchas cosas durante un período de tiempo (especialmente con la versión jdk 1.5) en el frente de concurrencia.

Puedes lograr lo mismo con la API java.util.concurrent. Algunos de los ejemplos son

  1. Uso de invokeAll en ExecutorService
  2. Usando CountDownLatch
  3. Usando ForkJoinPool o newWorkStealingPool of Executors (desde java 8)

Consulte las preguntas relacionadas de SE:

espere hasta que todos los hilos terminen su trabajo en java


Esta es una pregunta favorita de la entrevista de Java .

Thread t1 = new Thread(new EventThread("e1")); t1.start(); Thread e2 = new Thread(new EventThread("e2")); t2.start(); while (true) { try { t1.join(); // 1 t2.join(); // 2 These lines (1,2) are in in public static void main break; } }

t1.join() significa que t1 dice algo así como " Quiero terminar primero ". Lo mismo es el caso con t2 . No importa quién inició la t1 o t2 (en este caso, el método main ), main esperará hasta que t1 y t2 finalicen su tarea.

Sin embargo, un punto importante para anotar, t1 y t2 ellos mismos se pueden ejecutar en paralelo independientemente de la secuencia de llamada de combinación en t1 y t2 . Es el hilo main/daemon que tiene que esperar .


Para citar el método Thread.join Thread.join() javadocs :

join() Espera a que este hilo muera.

Hay un hilo que está ejecutando su código de ejemplo que probablemente sea el hilo principal .

  1. El hilo principal crea e inicia los hilos t1 y t2 . Los dos hilos comienzan a ejecutarse en paralelo.
  2. El hilo principal llama a t1.join() para esperar a que termine el hilo t1 .
  3. El subproceso t1 completa y el método t1.join() retorna en el subproceso principal. Tenga en cuenta que t1 ya podría haber finalizado antes de que se realice la llamada join() en cuyo caso la llamada join() volverá inmediatamente.
  4. El hilo principal llama a t2.join() para esperar que termine el hilo t2 .
  5. El subproceso t2 finaliza (o podría haberse completado antes de que lo hiciera el subproceso t1 ) y el método t2.join() retorna en el subproceso principal.

Es importante comprender que los subprocesos t1 y t2 se han ejecutado en paralelo, pero el hilo principal que los inició debe esperar a que finalicen para poder continuar. Ese es un patrón común. Además, t1 y / o t2 podrían haber terminado antes de que el hilo principal invoque join() en ellos. Si es así, join() no esperará pero regresará inmediatamente.

t1.join() significa que t2 se detiene hasta que t1 termina?

No. El hilo principal que está llamando a t1.join() dejará de ejecutarse y esperará a que finalice el subproceso t1 . El subproceso t2 se ejecuta en paralelo y no se ve afectado por t1 o la llamada t1.join() .

En términos de try / catch, join() arroja InterruptedException lo que significa que el hilo principal que llama a join() puede ser interrumpido por otro hilo.

while (true) {

Tener las uniones en un ciclo while es un patrón extraño. Típicamente, usted haría la primera unión y luego la segunda combinación manejando la InterruptedException apropiadamente en cada caso. No es necesario ponerlos en un bucle.


Simplemente pon:
t1.join() regresa después de completar t1 .
No hace nada para enhebrar t1 , excepto esperar a que termine.
Naturalmente, el código que sigue a t1.join() se ejecutará solo después de que t1.join() regrese.


Una imagen vale mas que mil palabras.

Main thread-->----->--->-->--block##########continue--->----> / | | sub thread start()/ | join() | / | | ---sub thread----->--->--->--finish

Espero que sea útil, para obtener más información, haga clic here


digamos que nuestro hilo principal inicia los hilos t1. En algún punto del tiempo, nuestro hilo principal terminará de ejecutarse.
Ahora, si no llamamos al método t1.join (), el hilo principal terminará y en este caso t1 no tendrá la posibilidad de finalizar la ejecución.
Entonces, el método join () se asegura de que el hilo de llamada, el hilo principal en este caso, una vez que termine de ejecutarse, espere a que t1 termine de ejecutarse.
Una vez que t1 termina de ejecutarse, el hilo principal puede terminar.


join() significa esperar a que se complete un hilo. Este es un método de bloqueo. Su hilo principal (el que hace el join() ) esperará en la línea t1.join() hasta que t1 termine su trabajo, y luego hará lo mismo con t2.join() .