Java ThreadPoolExecutor isTerminated() Method

The ThreadPoolExecutor class in Java provides the isTerminated() method to check if all tasks have completed following a shutdown request. This guide will cover the usage of the isTerminated() method, explain how it works, and provide concise examples to demonstrate its functionality in real-world use cases.

Introduction

The isTerminated() method is used to check if the ThreadPoolExecutor has terminated. This method returns true if all tasks have completed following a shutdown request, otherwise, it returns false. It is useful for determining whether it is safe to proceed after requesting a shutdown of the executor.

isTerminated Method Syntax

The syntax for the isTerminated method is as follows:

public boolean isTerminated()
  • The method does not take any parameters.
  • The method returns a boolean value:
    • true if all tasks have completed following a shutdown request.
    • false otherwise.

Examples

Example 1: Basic Usage of isTerminated()

In this example, we create a ThreadPoolExecutor, submit multiple tasks, shut it down, and use the isTerminated() method to check if all tasks have completed.

import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

public class IsTerminatedExample {
    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) {
                    e.printStackTrace();
                }
                System.out.println("Task " + taskNumber + " completed by " + Thread.currentThread().getName());
            });
        }

        // Shutdown the executor
        executor.shutdown();

        // Check if the executor has 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 is not terminated yet...
Executing task 3 by pool-1-thread-1
Executor is not terminated yet...
Executing task 4 by pool-1-thread-2
Executor is not terminated yet...
Executing task 5 by pool-1-thread-1
Executor is not terminated yet...
Task 1 completed by pool-1-thread-1
Task 2 completed by pool-1-thread-2
Executor is not terminated yet...
Task 3 completed by pool-1-thread-1
Executor is not terminated yet...
Task 4 completed by pool-1-thread-2
Executor is not terminated yet...
Task 5 completed by pool-1-thread-1
Executor has terminated.

Example 2: Combining isTerminated() with awaitTermination()

In this example, we combine the isTerminated() method with the awaitTermination() method to wait for the completion of all tasks and then confirm the termination status.

import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class AwaitTerminationExample {
    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(() -> {
                System.out.println("Executing task " + taskNumber + " by " + Thread.currentThread().getName());
                try {
                    Thread.sleep(1500); // Simulate task execution
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Task " + taskNumber + " completed by " + Thread.currentThread().getName());
            });
        }

        // Shutdown the executor
        executor.shutdown();

        try {
            // Wait for all tasks to complete or timeout after 10 seconds
            if (executor.awaitTermination(10, 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-1
Executing task 5 by pool-1-thread-2
Executing task 6 by pool-1-thread-3
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-1
Task 5 completed by pool-1-thread-2
Task 6 completed by pool-1-thread-3
All tasks completed.
Executor has terminated.

Example 3: Using isTerminated() for Resource Cleanup

In this example, we use the isTerminated() method to perform resource cleanup after all tasks have completed.

import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

public class ResourceCleanupExample {
    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 < 4; i++) {
            final int taskNumber = i + 1;
            executor.submit(() -> {
                System.out.println("Executing task " + taskNumber + " by " + Thread.currentThread().getName());
                try {
                    Thread.sleep(1000); // Simulate task execution
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Task " + taskNumber + " completed by " + Thread.currentThread().getName());
            });
        }

        // Shutdown the executor
        executor.shutdown();

        // Check if the executor has 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();
            }
        }

        // Perform resource cleanup
        System.out.println("Executor has terminated. Performing resource cleanup...");
        // Resource cleanup logic here
    }
}

Output:

Executing task 1 by pool-1-thread-1
Executing task 2 by pool-1-thread-2
Executor is not terminated yet...
Executing task 3 by pool-1-thread-1
Task 1 completed by pool-1-thread-1
Executor is not terminated yet...
Executing task 4 by pool-1-thread-2
Task 2 completed by pool-1-thread-2
Executor is not terminated yet...
Task 3 completed by pool-1-thread-1
Executor is not terminated yet...
Task 4 completed by pool-1-thread-2
Executor has terminated. Performing resource cleanup...

Conclusion

The ThreadPoolExecutor.isTerminated() method in Java is used for checking if all tasks have completed following a shutdown request. By using this method, you can determine whether it is safe to proceed with actions that require all tasks to be completed, such as resource cleanup or application shutdown.

Comments