Comment attendre un nombre de threads à remplir?
Ce qui est une façon de se contenter d'attendre tous les processus à la fin? Par exemple, disons que j'ai:
public class DoSomethingInAThread implements Runnable{
public static void main(String[] args) {
for (int n=0; n<1000; n++) {
Thread t = new Thread(new DoSomethingInAThread());
t.start();
}
//wait for all threads' run() methods to complete before continuing
}
public void run() {
//do something here
}
}
Comment puis-je modifier cela pour que la main()
méthode des pauses au commentaire jusqu'à ce que tous les threads' run()
méthodes de sortie? Merci!
Vous devez vous connecter pour publier un commentaire.
Vous mettez tous les threads d'un tableau, à commencer tous, et ensuite une boucle
Chaque jointure bloc respectifs jusqu'à ce que le thread est terminé. Les Threads peuvent remplir dans un ordre différent de vous joindre à eux, mais ce n'est pas un problème: quand la boucle s'arrête, tous les threads sont terminés.
Un autre moyen serait de faire une
List
deThread
s, de créer et de lancer chaque thread, tout en ajoutant à la liste. Une fois que tout est lancé, en boucle par le biais de la liste et appelerjoin()
sur chacun d'eux. Il n'a pas d'importance quel ordre les threads terminer l'exécution, tout ce que vous devez savoir, c'est que par le temps que la deuxième boucle se termine en cours d'exécution, chaque thread aura terminé.Une meilleure approche est d'utiliser un ExecutorService et de ses méthodes:
À l'aide d'un ExecutorService (et tous les trucs nouveaux à partir de Java 5 la simultanéité des utilitaires) est incroyablement flexible, et l'exemple ci-dessus, à peine même les rayures de la surface.
Éviter de la classe Thread tout à fait et plutôt d'utiliser les plus hautes abstractions fournies en java.util.simultanées
La ExecutorService la classe fournit les méthode invokeAll qui semble faire tout ce que vous voulez.
au lieu de
join()
, qui est une ancienne API, vous pouvez utiliser CountDownLatch. J'ai modifié le code comme ci-dessous pour répondre à votre exigence.Explication:
CountDownLatch
a été initialisé avec le comte de 1000 selon votre condition.Chaque thread de travail
DoSomethingInAThread
va décrémenter laCountDownLatch
, qui a été adoptée dans le constructeur.Thread principal
CountDownLatchDemo
await()
jusqu'le comte est devenu zéro. Une fois que le comte est devenu zéro, vous obtiendrez en dessous de la ligne de sortie.Plus d'infos à partir de la documentation d'oracle page
Veuillez vous reporter à la question SE pour d'autres options:
attendre jusqu'à ce que tous les threads terminer leur travail en java
Martin K suggéré
java.util.concurrent.CountDownLatch
semble être une meilleure solution. Juste l'ajout d'un exemple pour la mêmeEnvisager d'utiliser
java.util.concurrent.CountDownLatch
. Exemples dans la documentation javadocEn fonction de vos besoins, vous pouvez également vouloir vérifier les classes CountDownLatch et CyclicBarrier dans le java.util.simultanées paquet. Ils peuvent être utiles si vous voulez que votre fils à attendre les uns les autres, ou si vous souhaitez exercer un contrôle plus précis sur la façon dont votre threads de s'exécuter (par exemple, en attente de leur exécution interne pour un autre thread pour régler certains de l'etat). Vous pouvez également utiliser un CountDownLatch à signaler tous de vos fils pour démarrer dans le même temps, au lieu de partir un par un, comme vous l'itération dans la boucle. La norme API docs avez un exemple de ceci, en plus de l'aide d'un autre CountDownLatch d'attendre que tous les threads pour achever leur exécution.
Si vous faites une liste des threads, vous pouvez faire une boucle à travers eux et .join() sur chaque, et la boucle sera fini lorsque tous les threads ont. Je n'ai pas essayé si.
http://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#join()
Ce serait un commentaire, mais je ne peux pas faire de commentaires pour l'instant.
Martin K, je suis curieux de savoir comment vous pouvez utiliser
ThreadGroup
. Avez-vous fait avant?Je vois que ci-dessus, vous suggérons de vérifier
activeCount
- mettre de côté Martin v Löwiss'inquiétude à propos de l'interrogation de côté pour le moment, j'ai un autre souci avecactiveCount
lui-même.Mise en garde: je n'ai pas essayé, donc je ne suis pas expert sur la question, mais selon la la documentation javadoc, il renvoie un estimation le nombre de threads actifs.
Personnellement, je serais réticent à essayer de construire un système sur une estimation. Avez-vous une autre idée sur comment le faire, ou suis-je une erreur de lecture de la javadoc?
Créer le thread de l'objet à l'intérieur de la première boucle for.
Et puis si ce que tout le monde ici est en train de dire.
Vous pouvez le faire avec l'Objet "ThreadGroup" et son paramètre activeCount:
Comme une alternative à CountDownLatch vous pouvez également utiliser CyclicBarrier par exemple
À utiliser CyclicBarrier dans ce cas de la barrière.await() devrait être la dernière déclaration, c'est à dire quand votre fil est accompli son travail. CyclicBarrier peut à nouveau être utilisé avec la méthode reset (). Pour citer la documentation javadoc:
Un CyclicBarrier prend en charge une option Praticable commande qui est exécutée une fois par barrière point, après le dernier thread dans la partie arrive, mais avant tout les threads sont libérés. Cette barrière d'action est utile pour mettre à jour partagée-état avant de l'une des parties de continuer.