As the ExecutorService document explains The shutdown() method will allow previously submitted tasks to execute before terminating
. So in my initial understand, all submitted task will still be finally completed when we kill thread through ctrl c. But it seemed the actually result is not.
The generation of the executorService as below:
CORE_POOL_SIZE = 1
return new ThreadPoolExecutor(CORE_POOL_SIZE, numConsumers,
KEEP_ALIVE_TIME, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(),
consumerThreadFactory);
And in my task, I will log some information the task code sample like this:
log.info("before come into sleep.....")
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
log.warn(" exception during sleep.....{}", request.getExecutionId());
e.printStackTrace();
}
log.info("after come into sleep...")
I submit several task and then terminal thread through control c, and the result is that only the log before come into sleep is print.
So I dont know whether my understand is correct that shutDown can ensure all submitted task be completed finally. I also google some similar question but find there are no explicit answer.
CodePudding user response:
Control c kills entire JVM
Pressing Control c on the console terminates the entire Java process running your threads. See Wikipedia.
You are interrupting the JVM. This is not a graceful way to interact with your Java app.
So, no, you should not expect your executor service to continue running submitted tasks. You killed it.
The JVM is generally not designed to be manipulated in the console after launch. After launch, the only two ways I know of for interacting with the JVM is:
- The user-interface of your app, GUI or console-based.
- Java Management Extensions (JMX)
You said:
we kill thread through ctrl c
No, ctrl c does not specifically kill a thread. It kills your entire JVM.
awaitTermination
After calling ExecutorService#shutdown
, if you want your code to block and wait until all submitted tasks are done, call ExecutorService#awaitTermination
. Specify a certain amount of time to wait before throwing an exception if tasks are still running.
This waiting for termination is shown in the JavaDoc and has been discussed in many other Questions and Answers on Stack Overflow, some authored by me. So search to learn more.
CodePudding user response:
I believe it is clear from the docs for ExecutorService
(https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html#shutdown--) that it doesn't wait for the tasks to complete. We have awaitTermination
for this purpose.
This method does not wait for previously submitted tasks to complete execution. Use awaitTermination to do that.
A clear example of how to achieve this is available in Usage Example
section of this documentation as well.
Why is awaitTermination important during graceful shutdown?
Using shutdown()
is like informing your intention to stop all the threads managed by the ExecutorService
. There is no blocking involved here. Your main thread shall resume execution and continue executing subsequent code after shutdown()
. While handling graceful shutdown of a JVM (https://docs.oracle.com/javase/8/docs/technotes/guides/lang/hook-design.html), a separate thread will be called expecting it to complete its task and when it does complete, JVM shuts down. If you need to wait for the tasks to complete, block the shutdown hook thread using awaitTermination()
.