Keeping Track of Task Progress
To check the number of orders processed by a task, you use the OrderProcessorCallable object reference stored in the collection. The following code prints the task status at intervals of 1000ms until the orderVOQueue is empty:
private void printProcessorStatus() throws InterruptedException {
// print processor status until all orders are processed
while (!orderVOQueue.isEmpty()) {
for (Map.Entry<String, OrderProcessorCallable> e : callableMap
.entrySet()) {
Logger.log(e.getKey() + " processed order count: "
+ e.getValue().getProcessedCount());
}
Thread.sleep(1000);
}
}
Shutting Down ThreadPoolExecutor and Tasks Gracefully
The
ExecutorService.shutdown() method can be used for shutting down the executor. When you call
shutdown(), the executor initiates an orderly shutdown of all previously submitted tasks, and you may no longer submit new tasks. The following code calls the
shutdown() method so that no new tasks can be submitted. After that, it updates the running status of orderCallable to false, which will cause the
call method to return.
// shutdown() method will mark the thread pool shutdown to true
executor.shutdown();
// mark order processor callable to return
for (Map.Entry<String, OrderProcessorCallable> orderProcessor :
callableMap.entrySet()) {
orderProcessor.getValue().setRunning(false);
}
Forcing the ThreadPoolExecutor and Tasks to Shut Down
You can call the
ExecutorService.shutdownNow() method to force the executor to shut down. Again, after calling this method, you may no longer submit new tasks. It halts the processing of waiting tasks and attempts to stop actively running tasks by sending an interrupt.
ExecutorService.shutdownNow() also returns the list of tasks that were awaiting execution. Note that if actively running tasks failed to respond to
Thread.interrupt(), the call may run forever.
List<Runnable> notExecutedTasks = executor.shutdownNow();
You can cancel individual tasks by calling the Future.cancel(boolean mayInterruptIfRunning) method. The true value means an interrupt will be issued for an already executing task. If the task has not yet started, it will not be run. You can check a task's cancellation status using Future.isCancelled(), which returns true if the task was cancelled before it completed normally.