I'm performing some heavy work as follows:
try {
Input in = initInput(param);
Result re = doHeavyWork(in);
saveResultSomewhereElse(re);
} catch (Exception e) {
logExecutionError(e);
}
Furthermore, sometimes the doHeavyWork
takes too long that we ought to kill it manually to save resources. Nevertheless, I'd like to do logExecutionError
in that case.
Transforming the code block above into CompletableFuture
, we might get:
CompletableFuture.completedFuture(param)
.thenApply(initInput)
.thenApplyAsync(doHeavyWork, dedicatedExecutorService)
.thenApply(saveResultSomewhereElse)
.exceptionally(logExecutionError);
My question is that if I terminate the dedicatedExecutorService
, will the heavy work be really killed and the logExecutionError
is guaranteed to execute?
CodePudding user response:
Short answer: no. The somewhat longer answer is that there is no good way to terminate a thread in Java unless it cooperates. Thread#stop should not be used and is not available on ExecutorService. When you shutdown an executor service it can ask jobs to stop by interrupting them, but it cannot force them to stop. If doHeavyWork
handles interrupts and stops, then it will exit gracefully or with an exception (depending on how you have designed it) and the next stage can proceed.
Honestly I'm not sure if the code in thenApply
will run if the executor service has been stopped. Personally I would stop and interrupt doHeavyWork
without stopping the pool. Then you are in full control and can keep the executor service for other tasks.