Java ThreadPoolExecutor shutdownNow() Method

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