Concurrency
How do I gracefully shut down an ExecutorService?
To gracefully shut down an ExecutorService in Java, you should follow these steps: Call shutdown(): This will prevent the ExecutorService from accepting any new tasks while allowing already submitted tasks to be completed. Wait for Termination: You can use awaitTermination(long timeout, TimeUnit unit) to wait for a specified amount of time for all tasks to […]
Article by Wayan · Source: Kode Java ↗
To gracefully shut down an ExecutorService in Java, you should follow these steps:
- Call
shutdown():- This will prevent the
ExecutorServicefrom accepting any new tasks while allowing already submitted tasks to be completed.
- This will prevent the
- Wait for Termination:
- You can use
awaitTermination(long timeout, TimeUnit unit)to wait for a specified amount of time for all tasks to finish their execution.
- You can use
- Force Shutdown if Necessary:
- If tasks haven’t completed after the wait period, you can call
shutdownNow()to attempt to cancel all currently executing tasks and halt further task execution.
- If tasks haven’t completed after the wait period, you can call
Here’s an example:
package org.kodejava.util.concurrent;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class GracefulShutdownExample {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(5);
// Submit some tasks to the executor
for (int i = 0; i < 10; i++) {
executorService.submit(() -> {
try {
System.out.println("Task executing: " + Thread.currentThread().getName());
Thread.sleep(1000); // Simulate task processing
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("Task interrupted: " + Thread.currentThread().getName());
}
});
}
// Initiate graceful shutdown
executorService.shutdown();
System.out.println("Shutdown initiated");
try {
// Wait for all tasks to finish execution or timeout
if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) {
System.out.println("Timeout reached, forcing shutdown...");
// Force shutdown if tasks are still running
executorService.shutdownNow();
// Wait again to ensure shutdownNow has time to interrupt tasks
if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) {
System.err.println("Executor did not terminate");
}
}
} catch (InterruptedException e) {
// Re-cancel if the current thread was interrupted
executorService.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
System.out.println("Executor service shut down");
}
}
Explanation of Key Methods:
shutdown():- Initiates an orderly shutdown where previously submitted tasks are executed but no new tasks are accepted.
awaitTermination(long timeout, TimeUnit unit):- Waits for the executor to terminate for the given timeout. Returns
trueif termination occurs within the timeout,falseotherwise.
- Waits for the executor to terminate for the given timeout. Returns
shutdownNow():- Attempts to stop all running tasks and halts task processing. It returns a list of tasks that were waiting to be executed.
Best Practices:
- Always include exception handling for
InterruptedException. - Use a timeout value that suits your application’s requirements.
- Avoid forcing a shutdown (
shutdownNow()) unless absolutely necessary, as it can leave tasks in an inconsistent state.
By following these steps, you can shut down your ExecutorService gracefully and ensure that resources are properly released.
Comments 0
Share your questions, experiences, or feedback about this article.
Sign in with Google to leave a comment.
Sign in with Google
No comments yet. Be the first to share your feedback.