How do you correctly and safely shut down an ExecutorService?
The recommended approach is a two-phase shutdown. First call executor.shutdown(), which stops the executor from accepting new tasks but allows any tasks already submitted to finish running. Then call executor.awaitTermination(60, TimeUnit.SECONDS) to block for up to a chosen timeout while those in-flight tasks complete. If the executor still hasn't terminated after that wait, call executor.shutdownNow(), which attempts to interrupt all actively running tasks and returns a list of the tasks that were queued but never started, and then call awaitTermination() again to confirm everything has actually stopped. As of Java 19, ExecutorService also implements AutoCloseable, so wrapping its use in a try-with-resources block, such as try (ExecutorService e = ...) { ... }, will automatically call shutdown() and wait for termination when the block exits.
Ready to master this question?
Generate a complete walkthrough — background, the full answer in plain language, a working code example explained line by line, a real-world scenario, common mistakes, and how this same question gets asked in different ways.
Sign in to generate a response