web-dev-qa-db-fra.com

Thread.join () équivalent dans l'exécuteur

J'ai une question de débutant. J'ai ce code:

public class Main 
{

    public static void main(String[] args) throws InterruptedException 
    {
        // TODO Auto-generated method stub
        IntHolder aHolder=new IntHolder();
        aHolder.Number=0;

        IncrementorThread A= new IncrementorThread(1, aHolder);
        IncrementorThread B= new IncrementorThread(2, aHolder);
        IncrementorThread C= new IncrementorThread(3, aHolder);

        A.start();
        B.start();
        C.start();

        A.join();
        B.join();
        C.join();
        System.out.println("All threads completed...");

    }

}

Ce qui attendra que toutes les discussions se terminent. Si j'utilise Executors comme ceci:

public class Main 
{

    public static void main(String[] args) 
    {
        // TODO Auto-generated method stub
        IntHolder aHolder=new IntHolder();
        aHolder.number=0;

        IncrementalRunable A= new IncrementalRunable(1, aHolder);
        IncrementalRunable B= new IncrementalRunable(2, aHolder);
        IncrementalRunable C= new IncrementalRunable(3, aHolder);

        ExecutorService exec = Executors.newFixedThreadPool(3);
        exec.execute(A);
        exec.execute(B);
        exec.execute(C);
        //Don't know what to do here

        System.out.println("All threads completed...");
    }
}

Comment puis-je suspendre le thread principal pour attendre que tous les threads de l'exécuteur soient terminés, c'est-à-dire que "Tous les threads terminés ..." doit être imprimé après que tous les threads ont terminé leur travail?

17
Mario Stoilov
executor.shutdown();
while (!executor.awaitTermination(24L, TimeUnit.HOURS)) {
    System.out.println("Not yet. Still waiting for termination");
}

Utilisez la combinaison shutdown() + awaitTermination().

EDIT:

Basé sur le commentaire de @Lital

List<Callable<Object>> calls = new ArrayList<Callable<Object>>();
calls.add(Executors.callable(new IncrementalRunable(1, aHolder)));
calls.add(Executors.callable(new IncrementalRunable(2, aHolder)));
calls.add(Executors.callable(new IncrementalRunable(3, aHolder)));

List<Future<Object>> futures = executor.invokeAll(calls);

REMARQUE: invokeAll() ne sera renvoyé que lorsque toutes les tâches seront terminées (que ce soit en échouant ou en achevant son exécution).

13
Narendra Pathai

Vous ne devriez pas utiliser l'exécuteur de cette manière si vous souhaitez attendre que les tâches soient terminées. Et si vous ne voulez pas/ne pouvez pas arrêter votre exécuteur en pool de threads? Ceci est plus recommandé. façon:

    ExecutorService exec = Executors.newFixedThreadPool(3);
    Collection<Future<?>> tasks = new LinkedList<Future<?>>();

    Future<T> future = exec.submit(A);
    tasks.add(future);
    future = exec.submit(B);
    tasks.add(future);
    future = exec.submit(C);
    tasks.add(future);

    // wait for tasks completion
    for (Future<?> currTask : tasks) {
            try {
                currTask.get();
            } catch (Throwable thrown) {
                Logger.error(thrown, "Error while waiting for thread completion");
            }
        }
20
Lital Kolog

Essayez de travailler avec le pool de threads de cette façon.

executor.shutdown();
executor.awaitTermination(MAX_PRIORITY, TimeUnit.HOURS);
0