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.
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
- Uso de invokeAll en
ExecutorService
- Usando CountDownLatch
- 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 .
- El hilo principal crea e inicia los hilos
t1
yt2
. Los dos hilos comienzan a ejecutarse en paralelo. - El hilo principal llama a
t1.join()
para esperar a que termine el hilot1
. - El subproceso
t1
completa y el métodot1.join()
retorna en el subproceso principal. Tenga en cuenta quet1
ya podría haber finalizado antes de que se realice la llamadajoin()
en cuyo caso la llamadajoin()
volverá inmediatamente. - El hilo principal llama a
t2.join()
para esperar que termine el hilot2
. - El subproceso
t2
finaliza (o podría haberse completado antes de que lo hiciera el subprocesot1
) y el métodot2.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()
.