Comment attendre simplement la fin de tous les processus threadés? 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 s'arrête au commentaire jusqu'à ce que toutes les run()
méthodes des threads se terminent? Merci!
java
multithreading
parallel-processing
wait
DivideByHero
la source
la source
Une façon serait de faire un
List
deThread
s, de créer et de lancer chaque thread, tout en l'ajoutant à la liste. Une fois que tout est lancé, parcourez la liste et appelezjoin()
chacun d'eux. Peu importe l'ordre dans lequel les threads finissent de s'exécuter, tout ce que vous devez savoir est que lorsque la seconde boucle se termine, chaque thread sera terminé.Une meilleure approche consiste à utiliser un ExecutorService et ses méthodes associées:
L'utilisation d'un ExecutorService (et de toutes les nouvelles fonctionnalités des utilitaires de concurrence de Java 5 ) est incroyablement flexible, et l'exemple ci-dessus efface à peine la surface.
la source
la source
au lieu de
join()
, qui est une ancienne API, vous pouvez utiliser CountDownLatch . J'ai modifié votre code comme ci-dessous pour répondre à vos besoins.Explication :
CountDownLatch
a été initialisé avec un nombre donné de 1000 selon vos besoins.Chaque thread de travail
DoSomethingInAThread
décrémentera leCountDownLatch
, qui a été passé dans le constructeur.Fil principal
CountDownLatchDemo
await()
jusqu'à ce que le compte soit devenu zéro. Une fois que le compte est devenu zéro, vous serez en dessous de la ligne en sortie.Plus d'informations sur la page de documentation d'Oracle
Reportez-vous à la question SE associée pour d'autres options:
attendez que tous les threads aient terminé leur travail en java
la source
Évitez complètement la classe Thread et utilisez à la place les abstractions supérieures fournies dans java.util.concurrent
La classe ExecutorService fournit la méthode invokeAll qui semble faire exactement ce que vous voulez.
la source
Pensez à utiliser
java.util.concurrent.CountDownLatch
. Exemples dans javadocsla source
Comme l'a suggéré Martin K, cela
java.util.concurrent.CountDownLatch
semble être une meilleure solution. Juste en ajoutant un exemple pour le mêmela source
En fonction de vos besoins, vous pouvez également consulter les classes CountDownLatch et CyclicBarrier dans le package java.util.concurrent. Ils peuvent être utiles si vous voulez que vos threads attendent les uns les autres, ou si vous voulez un contrôle plus fin sur la manière dont vos threads s'exécutent (par exemple, attendre dans leur exécution interne qu'un autre thread définisse un état). Vous pouvez également utiliser un CountDownLatch pour signaler à tous vos threads de démarrer en même temps, au lieu de les démarrer un par un lorsque vous parcourez votre boucle. Les documents API standard en ont un exemple, ainsi que l'utilisation d'un autre CountDownLatch pour attendre que tous les threads aient terminé leur exécution.
la source
Si vous faites une liste des threads, vous pouvez les parcourir en boucle et .join () contre chacun d'eux, et votre boucle se terminera lorsque tous les threads auront. Je ne l'ai pas essayé cependant.
http://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#join ()
la source
Créez l'objet thread à l'intérieur de la première boucle for.
Et puis ce que tout le monde dit ici.
la source
Vous pouvez le faire avec l'objet "ThreadGroup" et son paramètre activeCount :
la source
Comme alternative à CountDownLatch, vous pouvez également utiliser CyclicBarrier par exemple
Pour utiliser CyclicBarrier dans ce cas, barrière.await () doit être la dernière instruction, c'est-à-dire lorsque votre thread a terminé son travail. CyclicBarrier peut être réutilisé avec sa méthode reset (). Pour citer des javadocs:
Un CyclicBarrier prend en charge une commande exécutable facultative qui est exécutée une fois par point de barrière, après l'arrivée du dernier thread de la partie, mais avant la libération des threads. Cette action de barrière est utile pour mettre à jour l'état partagé avant que l'une des parties ne continue.
la source
Le
join()
n'a pas été utile pour moi. voir cet exemple à Kotlin:Le résultat:
Maintenant, laissez-moi utiliser les
join()
threads pour:Et le résultat:
Comme il est clair lorsque nous utilisons le
join
:Notre solution pour éviter de bloquer d'autres threads était de créer une ArrayList:
Maintenant, lorsque nous voulons démarrer un nouveau thread, nous l'ajoutons le plus à ArrayList:
La
addThreadToArray
fonction:La
startNewThread
fonction:Vérifiez l'achèvement des threads comme ci-dessous partout où c'est nécessaire:
la source