Search code examples
javaexecutorserviceexecutor

How is an executor terminated in my Java program?


This question is related to my previous question : Why the speed of a Java process inside multiple loops slows down as it goes?

In order to find the problem of that question, I looked closely at my code and found some executors in my app are not terminated, since I'm in the process of learning how to use executors, I copied some online sample codes and used them in my app, and I'm not sure if I'm using them correctly.

What's the difference between the following 2 approaches of using executors ?

[1]

 Executor executor=Executors.newFixedThreadPool(30);
 CountDownLatch doneSignal=new CountDownLatch(280);

 for (int N=0;N<280;N++)
 {
   ...
   executor.execute(new SampleCountRunner(doneSignal,...));
 }
 try { doneSignal.await(); }
 catch (Exception e) { e.printStackTrace(); }

[2]

ExecutorService executor=Executors.newFixedThreadPool(30);

for (int i=0;i<60;i++)
{
  ...
  executor.execute(new xyzRunner(...));
}
executor.shutdown();

while (!executor.isTerminated()) { }

It seems to me after the 1st one is done, the executor still has an active pool of threads running and waiting for more tasks, they DO consume cpu time and memory.

The 2nd one will terminate all active threads in the pool after the shutdown() method is run, and all previously active threads won't take any more cpu time or memory after that point.

So my questions are :

[1] Am I correct ?

[2] How to terminate the pool of threads in the 1st case ? There is no "executor.shutdown()" for Executor

Edit :

Problem solved, I changed Executor in [1] to ExecutorService, and added :

   executor.shutdown();
   while (!executor.isTerminated()) { }

Now when my program ends, it won't have a lot of threads active any more.


Solution

  • It seems to me after the 1st one is done, the executor still has an active pool of threads running and waiting for more tasks, they DO consume cpu time and memory.

    Not exactly. In first approach , after the tasks are all done ( as signalled by the latch ) , the executor is definitely NOT shutdown - but the threads in the executor do NOT consume cpu ( they consume minimum memory needed for thier structures yes ).

    In this approach - you are explicitly in control of knowing when and how your tasks are completed. You can know if the tasks have succeeded or failed , and can decide to resubmit the tasks if needed.

    The 2nd one will terminate all active threads in the pool after the shutdown() method is run, and all previously active threads won't take any more cpu time or memory after that point.

    Again ,not exactly .In this approach , the ExecutorService does not shutdown immediately after the call to shutdown(). It waits for the already submitted tasks to complete , but here you do not directly know if these tasks completed successfully or they failed ( by throwing some Exception ).

    And until the already submitted tasks are completed - your isShutDown() will do a tight loop ( it will spike the cpu to near 100% ) .