167 votes

Que signifie ce code d'accès au fil ?

Dans ce code, que signifient les termes "jointure" et "rupture" ? t1.join() causes t2 de s'arrêter jusqu'à ce que t1 se termine ?

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();
   }
}

337voto

Gray Points 58585

Que signifie ce code d'accès au fil ?

Pour citer le Thread.join() javadocs des méthodes :

join() Attend que ce fil de discussion meure.

Il y a un thread qui exécute votre exemple de code qui est probablement le fil conducteur .

  1. Le thread principal crée et démarre le t1 y t2 fils. Les deux threads commencent à fonctionner en parallèle.
  2. Le fil principal appelle t1.join() pour attendre le t1 fil pour finir.
  3. Le site t1 se termine et le t1.join() revient dans le fil d'exécution principal. Notez que t1 pourrait déjà avoir terminé avant le join() est effectué, auquel cas l'appel join() l'appel reviendra immédiatement.
  4. Le fil principal appelle t2.join() pour attendre le t2 fil pour finir.
  5. Le site t2 se termine (ou il peut s'être terminé avant que le processus de l t1 a fait) et le t2.join() revient dans le fil d'exécution principal.

Il est important de comprendre que le t1 y t2 les fils de discussion sont en cours en parallèle mais le fil principal qui les a lancés doit attendre qu'ils se terminent avant de pouvoir continuer. C'est un schéma courant. Aussi, t1 et/ou t2 aurait pu terminer avant le fil principal appelle join() sur eux. Si c'est le cas, alors join() n'attendra pas mais reviendra immédiatement.

t1.join() signifie faire en sorte que t2 s'arrête jusqu'à ce que t1 se termine ?

Non. Le principal qui appelle t1.join() s'arrêtera de fonctionner et attendra que le t1 fil pour finir. Le site t2 s'exécute en parallèle et n'est pas affectée par l'opération t1 ou le t1.join() appeler du tout.

En ce qui concerne le try/catch, le join() jette InterruptedException ce qui signifie que le thread principal qui appelle join() peut lui-même être interrompu par un autre thread.

while (true) {

Le fait d'avoir les jointures dans un while La boucle est un modèle étrange. En général, vous effectuez la première jointure, puis la seconde, en manipulant le bouton InterruptedException de manière appropriée dans chaque cas. Il n'est pas nécessaire de les mettre dans une boucle.

76voto

AmitG Points 2060

Il s'agit d'un interview Java préférée question.

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() signifie que t1 dit quelque chose comme " Je veux finir en premier ". C'est également le cas avec t2 . Peu importe qui a commencé t1 o t2 (dans ce cas, le main ), main attendra que t1 y t2 terminer leur tâche.

Cependant, un point important à noter, t1 y t2 eux-mêmes peuvent s'exécuter en parallèle, quelle que soit la séquence d'appels de jointure. sur t1 y t2 . C'est le main/daemon fil qui doit attendre .

53voto

Avi Points 4056

join() signifie attendre qu'un fil se termine. Il s'agit d'une méthode de blocage. Votre thread principal (celui qui fait le join() ) attendra le t1.join() ligne jusqu'à ce que t1 termine son travail, et fera ensuite de même pour t2.join() .

44voto

xxy Points 13

Une image vaut mille mots.

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

En espérant que cela soit utile, pour plus de détails, cliquez sur aquí

12voto

Ivan Golovach Points 109

Lorsque le thread tA appelle tB.join(), il n'attend pas seulement que tB meure ou que tA soit lui-même interrompu, mais il crée une relation "happens-before" entre la dernière déclaration de tB et la déclaration suivante après tB.join() dans le thread tA.

Toutes les actions d'un thread se produisent avant qu'un autre thread ne revienne avec succès d'un join() sur ce thread.

Cela signifie que le programme

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);
    }
}

Toujours imprimer

>> 1111111111111111111111111 ...

Mais le programme

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);
    }
}

Peut imprimer non seulement

>> 0000000000 ... 000000111111111111111111111111 ...

Mais

>> 00000000000000000000000000000000000000000000 ... 

Toujours uniquement '0'.

Parce que le modèle de mémoire Java n'exige pas le "transfert" de la nouvelle valeur de "sharedVar" du threadB au thread principal sans relation heppens-before (démarrage du thread, thread join, utilisation du mot clé "synchonized", utilisation des variables AtomicXXX, etc).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X