36

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?

user152468
  • 3,202
  • 6
  • 27
  • 57
Mario Stoilov
  • 3,411
  • 5
  • 31
  • 51

5 Answers5

27

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");
            }
        }
Lital Kolog
  • 1,301
  • 14
  • 39
  • I agree that I shouldn't use executors like that, but I am just fooling around with java now and I was curios as to how I could achieve that – Mario Stoilov Dec 10 '13 at 13:56
24
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).

Narendra Pathai
  • 41,187
  • 18
  • 82
  • 120
  • 2
    Don't you think it is not good practice to shutdown a thread pool just for the sake of a simple join? – Lital Kolog Dec 10 '13 at 13:45
  • 1
    @Lital I have added another nifty approach that can be followed. – Narendra Pathai Dec 10 '13 at 13:56
  • @NarendraPathai, great, this is even better, but change the numbers to be 1,2,3 (those are thread numbers I use to print messages) – Mario Stoilov Dec 10 '13 at 13:59
  • Btw: there is no _need_ to await the termination unless you need to react on it. So if all you do afterwards is to end the program, a simple `shutdown()` call is enough, if you know that threads will terminate properly. Otherwise a forceful `shutdownNow()` is required as a reaction to `shutdown()`. – TwoThe Dec 10 '13 at 14:25
  • @MarioStoilov Done, a typo :) – Narendra Pathai Dec 10 '13 at 14:57
1

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();
    }
0

Try working with thread pool this way.

executor.shutdown();
executor.awaitTermination(MAX_PRIORITY, TimeUnit.HOURS);
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
-2
 exec.shutdown();
    // Wait until all threads are finish
    exec.awaitTermination();
Satheesh Cheveri
  • 3,621
  • 3
  • 27
  • 46