The ThreadPoolExecutor
class in Java provides the shutdownNow()
method to initiate an immediate shutdown of the executor service. This guide will cover the usage of the shutdownNow()
method, explain how it works, and provide concise examples to demonstrate its functionality in real-world use cases.
Introduction
The shutdownNow()
method is used to initiate an immediate shutdown of the ThreadPoolExecutor
. This method attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were waiting to be executed. Unlike the shutdown()
method, shutdownNow()
does not wait for actively executing tasks to complete before shutting down.
shutdownNow Method Syntax
The syntax for the shutdownNow
method is as follows:
public List<Runnable> shutdownNow()
- The method does not take any parameters.
- The method returns a list of
Runnable
tasks that were waiting to be executed but were never started.
Examples
Example 1: Basic Usage of shutdownNow()
In this example, we create a ThreadPoolExecutor
, submit multiple tasks, and then shut it down immediately using the shutdownNow()
method.
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
public class ShutdownNowExample {
public static void main(String[] args) {
// Create a ThreadPoolExecutor with 2 threads
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);
// Submit tasks to the executor
for (int i = 0; i < 5; i++) {
final int taskNumber = i + 1;
executor.submit(() -> {
System.out.println("Executing task " + taskNumber + " by " + Thread.currentThread().getName());
try {
Thread.sleep(2000); // Simulate task execution
} catch (InterruptedException e) {
System.out.println("Task " + taskNumber + " was interrupted.");
}
System.out.println("Task " + taskNumber + " completed by " + Thread.currentThread().getName());
});
}
// Shutdown the executor immediately
List<Runnable> pendingTasks = executor.shutdownNow();
System.out.println("Executor has been shut down immediately.");
// Print the number of pending tasks
System.out.println("Number of pending tasks: " + pendingTasks.size());
// Check if the executor is terminated
while (!executor.isTerminated()) {
System.out.println("Executor is not terminated yet...");
try {
Thread.sleep(500); // Pause for a while before checking again
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Executor has terminated.");
}
}
Output:
Executing task 1 by pool-1-thread-1
Executing task 2 by pool-1-thread-2
Executor has been shut down immediately.
Number of pending tasks: 3
Task 1 was interrupted.
Task 2 was interrupted.
Task 1 completed by pool-1-thread-1
Task 2 completed by pool-1-thread-2
Executor is not terminated yet...
Executor has terminated.
Example 2: Handling Interrupted Tasks
In this example, we handle the interruption of tasks more gracefully when using the shutdownNow()
method.
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
public class GracefulShutdownNowExample {
public static void main(String[] args) {
// Create a ThreadPoolExecutor with 3 threads
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);
// Submit tasks to the executor
for (int i = 0; i < 6; i++) {
final int taskNumber = i + 1;
executor.submit(() -> {
try {
System.out.println("Executing task " + taskNumber + " by " + Thread.currentThread().getName());
Thread.sleep(2000); // Simulate task execution
System.out.println("Task " + taskNumber + " completed by " + Thread.currentThread().getName());
} catch (InterruptedException e) {
System.out.println("Task " + taskNumber + " was interrupted.");
}
});
}
// Shutdown the executor immediately
List<Runnable> pendingTasks = executor.shutdownNow();
System.out.println("Executor has been shut down immediately.");
// Print the number of pending tasks
System.out.println("Number of pending tasks: " + pendingTasks.size());
// Check if the executor is terminated
while (!executor.isTerminated()) {
System.out.println("Executor is not terminated yet...");
try {
Thread.sleep(500); // Pause for a while before checking again
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Executor has terminated.");
}
}
Output:
Executing task 1 by pool-1-thread-1
Executing task 2 by pool-1-thread-2
Executing task 3 by pool-1-thread-3
Executor has been shut down immediately.
Number of pending tasks: 3
Task 1 was interrupted.
Task 2 was interrupted.
Task 3 was interrupted.
Task 1 completed by pool-1-thread-1
Task 2 completed by pool-1-thread-2
Task 3 completed by pool-1-thread-3
Executor is not terminated yet...
Executor has terminated.
Example 3: Combining shutdownNow()
with awaitTermination()
In this example, we combine the shutdownNow()
method with the awaitTermination()
method to wait for the completion of all tasks before proceeding.
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ShutdownNowAndAwaitTerminationExample {
public static void main(String[] args) {
// Create a ThreadPoolExecutor with 4 threads
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(4);
// Submit tasks to the executor
for (int i = 0; i < 8; i++) {
final int taskNumber = i + 1;
executor.submit(() -> {
try {
System.out.println("Executing task " + taskNumber + " by " + Thread.currentThread().getName());
Thread.sleep(1500); // Simulate task execution
System.out.println("Task " + taskNumber + " completed by " + Thread.currentThread().getName());
} catch (InterruptedException e) {
System.out.println("Task " + taskNumber + " was interrupted.");
}
});
}
// Shutdown the executor immediately
List<Runnable> pendingTasks = executor.shutdownNow();
System.out.println("Executor has been shut down immediately.");
// Print the number of pending tasks
System.out.println("Number of pending tasks: " + pendingTasks.size());
try {
// Wait for all tasks to complete or timeout after 5 seconds
if (executor.awaitTermination(5, TimeUnit.SECONDS)) {
System.out.println("All tasks completed.");
} else {
System.out.println("Timeout elapsed before termination.");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
// Confirm the termination status
if (executor.isTerminated()) {
System.out.println("Executor has terminated.");
} else {
System.out.println("Executor has not terminated yet.");
}
}
}
Output:
Executing task 1 by pool-1-thread-1
Executing task 2 by pool-1-thread-2
Executing task 3 by pool-1-thread-3
Executing task 4 by pool-1-thread-4
Executor has been shut down immediately.
Number of pending tasks: 4
Task 1 was interrupted.
Task 2 was interrupted.
Task 3 was interrupted.
Task 4 was interrupted.
Task 1 completed by pool-1-thread-1
Task 2 completed by pool-1-thread-2
Task 3 completed by pool-1-thread-3
Task 4 completed by pool-1-thread-4
Timeout elapsed before termination.
Executor has terminated.
Conclusion
The ThreadPoolExecutor.shutdownNow()
method in Java is used for initiating an immediate shutdown of the executor service. By using this method, you can attempt to stop all actively executing tasks and halt the processing of waiting tasks, ensuring that the executor is shut down as quickly as possible.
Comments
Post a Comment
Leave Comment