1

I have a command line application. It runs a loop say 100 times and in the loop schedules a task using a thread. I am using ExecutorService so there are 4 threads running at any time.

After the loop ends, I want to print a summary message. E.g. time taken to complete all 100 tasks. When I stepped through the code the debugger went straight to the summary part, but the other tasks are still running. I understand this is because each thread runs on its own. So how do I print messages only after all threads complete?

ExecutorService exec = Executors.newFixedThreadPool(4);

long startTime = System.currentTimeMillis();

for (int i = 0; i < 100; i++) {

    Runnable requestHandler = new Runnable() {
        @Override
        public void run() {
            try {
                // call task function in here
            } catch (Exception ex) {
            }
        }
    };
    exec.execute(requestHandler);
}

exec.shutdown();

long endTime = System.currentTimeMillis();

LOGGER.info("******************SUMMARY******************");
LOGGER.info("Time taken : " + ((endTime - startTime)/1000) + " seconds, " 
                            + ((endTime - startTime)/1000/60) + " minutes");
Dogmatixed
  • 794
  • 1
  • 11
  • 33
user373201
  • 10,945
  • 34
  • 112
  • 168
  • After some more googling. I ended up using CountDownLatch. An example is here http://www.javamex.com/tutorials/threads/CountDownLatch.shtml – user373201 Nov 17 '11 at 14:55

4 Answers4

5

From the main-thread, you could create another thread that does everything from declaring exec to exec.shutdown();. After creating this thread, you put the main-thread to wait. At the end of the new thread's actions(after exec.shutdown();) you should notify it.

Dragos
  • 2,911
  • 12
  • 39
  • 55
3

See http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html example copied for brevity

 void shutdownAndAwaitTermination(ExecutorService pool) {
   pool.shutdown(); // Disable new tasks from being submitted
   try {
     // Wait a while for existing tasks to terminate
     if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
       pool.shutdownNow(); // Cancel currently executing tasks
       // Wait a while for tasks to respond to being cancelled
       if (!pool.awaitTermination(60, TimeUnit.SECONDS))
           System.err.println("Pool did not terminate");
     }
   } catch (InterruptedException ie) {
     // (Re-)Cancel if current thread also interrupted
     pool.shutdownNow();
     // Preserve interrupt status
     Thread.currentThread().interrupt();
   }
 }
Prashant Bhate
  • 10,907
  • 7
  • 47
  • 82
1

Basically you need to wait until the ExecutorService isTerminated() method returns true. You can use awaitTermination() to that end.

pushy
  • 9,535
  • 5
  • 26
  • 45
0

The solution for you based on your code:

ExecutorService exec = Executors.newFixedThreadPool(4);
long start = System.currentTimeMillis();
//Your code
exec.shutdown();
while(true) {
  if(exec.isTerminated()) {
    long end = System.currentTimeMillis();
    System.out.println("Time : " + (end - start));  
    break;
  }

Check this out! It works!