Question

I have a newbie question. I have this 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...");

    }

}

Which will wait for all threads to complete. If I use Executors like this:

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

How can I suspend the main thread to wait for all the threads in the executor to finish, i.e the "All threads completed..." should be printed after the all the threads have done their work?

Was it helpful?

Solution 2

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

Use shutdown() + awaitTermination() combination.

EDIT:

Based on the comment of @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);

NOTE: invokeAll() will not return until all the tasks are completed (either by failing or completing successful execution).

OTHER TIPS

You shouldn't use executor like this if you want to wait for tasks to finish. What if you don't want/can't shutdown your thread pool executor? This is a more recommended way:

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

We can use below code to join the thread.

 executor.execute(new YouThread());

    try{     
         executor.shutdown();
         while (!executor.awaitTermination(24L, TimeUnit.HOURS)) {
             System.out.println("Not yet. Still waiting for termination");
         }                
    }catch(InterruptedException e){
        e.printStackTrace();
    }

Try working with thread pool this way.

executor.shutdown();
executor.awaitTermination(MAX_PRIORITY, TimeUnit.HOURS);
 exec.shutdown();
    // Wait until all threads are finish
    exec.awaitTermination();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top