Question

Je suis en train d'écrire un code qui engendrera deux fils, puis attendre pour eux de se synchroniser à l'aide de la classe CyclicBarrier. Le problème est que la barrière cyclique ne fonctionne pas comme prévu et le principal ne marche pas de fil d'attente pour les fils individuels pour terminer. Voici comment mon code ressemble:

 class mythread extends Thread{
   CyclicBarrier barrier;
   public mythread(CyclicBarrier barrier) { 
       this.barrier = barrier;
      }

   public void run(){
            barrier.await();
       } 
 }



class MainClass{
 public void spawnAndWait(){
    CyclicBarrier barrier = new CyclicBarrier(2);
    mythread thread1 = new mythread(barrier).start();
    mythread thread2 = new mythread(barrier).start();
    System.out.println("Should wait till both threads finish executing before printing this");
  }
}

Toute idée de ce que je fais mal? Ou est-il une meilleure façon d'écrire ces méthodes de synchronisation de barrière? S'il vous plaît aider.

Était-ce utile?

La solution

Lors de l'exécution de votre thread principal vous créez deux autres fils et leur dire d'attendre les uns des autres. Mais vous avez écrit rien à faire de votre fil conducteur d'attendre pour eux et se plaindre n'attend pas. Essayez

CyclicBarrier barrier = new CyclicBarrier(3);
mythread thread1 = new mythread(barrier).start();
mythread thread2 = new mythread(barrier).start();
barrier.await(); // now you wait for two new threads to reach the barrier.
System.out.println("Should wait till both threads finish executing before printing this");

BTW. Ne pas étendre la classe de fil à moins que vous devez. Mettre en œuvre Runnable et passer à la discussion des implémentations des objets. Comme ceci:

class MyRunnable implements Runnable {
    public void run(){
        // code to be done in thread
    }
}

Thread thread1 = new Thread(MyRunnable);
thread1.start();

EDIT Justification pour éviter étendre cette discussion.
La règle de base est aussi peu que possible le couplage. L'héritage est un lien très fort entre les classes. Vous devez hériter de fil si vous voulez changer une partie de son comportement par défaut (à savoir remplacer certaines méthodes) ou si vous voulez accéder à certains champs protégés de fil de classe. Si vous ne voulez pas, vous choisissez un couplage plus lâche -. Et la mise en œuvre Runnable passant comme paramètre constructeur à Enfiler exemple

Autres conseils

Passez une instance de Runnable au constructeur de votre CyclicBarrier comme celui-ci.

CyclicBarrier barrier = new CyclicBarrier(2, new Runnable() {

    @Override
    public void run() {
        System.out.println("Should wait till both threads finish executing before printing this");
    }
});

new mythread(barrier).start();
new mythread(barrier).start();

Vous cherchez Thread.join () méthode ...

thread1.join();
thread2.join();
System.out.println("Finished");

EDIT: en raison des commentaires ...

Et si vous ne voulez pas attendre pour toujours, vous pouvez également spécifier le nombre maximum de millisecondes, plus nanosecondes attendre le fil à mourir

Barrière cyclique n'est pas le bon choix dans ce cas. Vous devez utiliser CountDownLatch ici.

Je suppose que vous avez invoquez méthode spawnAndWait de la méthode principale.

La raison pour laquelle ce travail est que la coutume CyclicBarrier a 2 constructeurs. Pour effectuer, vous devez utiliser un constructeur de 2 paramètres post-opérations. La chose la plus importante à retenir est que le thread principal ne sera pas attendre par la méthode await; mais continuera à exécuter. Cependant, le fil spécifié dans le constructeur de CyclicBarrier ne fonctionne que lorsque toutes les discussions engendrées arrêtent à la barrière (par la méthode de await)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top