3

I an using ThreadPoolExecutor in java to excute multi threads, and I have to do something after threads finish, and have to wait.

So I want to ask what is the best way to do that?

Is that right I do in the way?

threadPool.shutdown();

boolean loop = true;
Integer x = threadPool.getPoolSize();
while (threadPool.getPoolSize() != 0) {
}
Ravindra babu
  • 37,698
  • 11
  • 250
  • 211
jsohpill
  • 51
  • 1
  • 6

2 Answers2

1

Shutdown will initiate an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.

    executor.shutdown();
    System.out.println("All tasks submitted...No new tasks will be admitted");

However, I would strongly recommend using awaitTermination as this will allow current thread to block until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first.

    try {
        executor.awaitTermination(3, TimeUnit.SECONDS);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

EDIT:

 The runState provides the main lifecyle control, taking on values:

 *   RUNNING:  Accept new tasks and process queued tasks
 *   SHUTDOWN: Don't accept new tasks, but process queued tasks
 *   STOP:     Don't accept new tasks, don't process queued tasks,
 *             and interrupt in-progress tasks
 *   TIDYING:  All tasks have terminated, workerCount is zero,
 *             the thread transitioning to state TIDYING
 *             will run the terminated() hook method
 *   TERMINATED: terminated() has completed

The numerical order among these values matters, to allow ordered comparisons. The runState monotonically increases over time, but need not hit each state. The transitions are:

RUNNING -> SHUTDOWN
On invocation of shutdown(), perhaps implicitly in finalize()

(RUNNING or SHUTDOWN) -> STOP
On invocation of shutdownNow()

SHUTDOWN -> TIDYING
When both queue and pool are empty

STOP -> TIDYING
When pool is empty

TIDYING -> TERMINATED
When the terminated() hook method has completed. Threads waiting in awaitTermination() will return when the state reaches TERMINATED.

Detecting the transition from SHUTDOWN to TIDYING is less straightforward than you'd like because the queue may become empty after non-empty and vice versa during SHUTDOWN state, but we can only terminate if, after seeing that it is empty, we see that workerCount is 0.

Going back to your question, when you call getPoolSize() it checks the state of the threadpool when it is in TIDYING state. Hence, I think the correct check should be against TERMINATED state. Although, the results are the same if you have not implemented terminated() method.

Suparna
  • 1,132
  • 1
  • 8
  • 20
  • Two reasons: 1. `while loop` is going to be CPU bound until your thread pool completes execution. On the other hand that is not the case with awaitTermination 2. The state of the executor is not yet Terminated when you use getPoolSize(). Although, you may have not implemented terminated() call and hence you should be fine. But for #1, I will recommend awaitTermination over a while loop. – Suparna Mar 25 '16 at 07:41
  • But it can't wait for all threads finish when just use try { executor.awaitTermination(3, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace(); } . the main process will Continue to run the code after that. It seems must to use while to stop the main process continue to run before threads finish. – jsohpill Mar 25 '16 at 08:38
  • sorry, I used it from one of my examples where I wanted to wait for 3 seconds. You can change it to: executor.awaitTermination(3, TimeUnit.DAY); – Suparna Mar 25 '16 at 08:44
  • :-) Thank you for your help. I still use while, beacuse I must wait for All thread finish, and I use awaitTermination. try { while (!threadPool.awaitTermination(1, TimeUnit.SECONDS)) { } } catch (InterruptedException e) { e.printStackTrace(); } – jsohpill Mar 28 '16 at 00:00
  • No problem. Just so that if you have found the information useful, you can upvote the response as well as select the best response. You are also going to get credit for closing the question. – Suparna Mar 28 '16 at 01:25
1

If you want to wait gracefully, refer to solutions in below question:

How to wait for completion of multiple tasks in Java?

If you are not using any of them ( invokeAll, CountDownLatch) and submit the jobs and waiting for executor to finish the tasks, refer to

How to forcefully shutdown java ExecutorService

Basic code snippet in this case:

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();
   }
Community
  • 1
  • 1
Ravindra babu
  • 37,698
  • 11
  • 250
  • 211