The ThreadPoolExecutor
class in Java provides the awaitTermination()
method to wait for the completion of all tasks in the executor after a shutdown request. This guide will cover the usage of the awaitTermination()
method, explain how it works, and provide concise examples to demonstrate its functionality in real-world use cases.
Introduction
The awaitTermination()
method is used to block the calling thread until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first. It is typically used in conjunction with shutdown()
or shutdownNow()
to ensure that the executor has completed all its tasks before proceeding.
awaitTermination Method Syntax
The syntax for the awaitTermination
method is as follows:
public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException
- The method takes two parameters:
timeout
- the maximum time to wait.unit
- the time unit of the timeout argument.
- The method returns a boolean value:
true
if the executor terminated within the given timeout.false
if the timeout elapsed before termination.
- The method throws
InterruptedException
if the current thread is interrupted while waiting.
Examples
Example 1: Basic Usage with Shutdown
In this example, we create a ThreadPoolExecutor
, submit tasks to it, shut it down, and use awaitTermination()
to wait for the completion of all tasks.
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 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());
});
}
// Shut down 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 successfully.");
} else {
System.out.println("Timeout elapsed before termination.");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Output:
Executing task 1 by pool-1-thread-1
Executing task 2 by pool-1-thread-2
Executing task 3 by pool-1-thread-1
Executing task 4 by pool-1-thread-2
Executing task 5 by pool-1-thread-1
Task 1 completed by pool-1-thread-1
Task 2 completed by pool-1-thread-2
Task 3 completed by pool-1-thread-1
Task 4 completed by pool-1-thread-2
Task 5 completed by pool-1-thread-1
All tasks completed successfully.
Example 2: Handling InterruptedException
In this example, we demonstrate how to handle the InterruptedException
that might be thrown by the awaitTermination()
method.
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class HandleInterruptedExceptionExample {
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());
});
}
// Shut down 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 successfully.");
} else {
System.out.println("Timeout elapsed before termination.");
}
} catch (InterruptedException e) {
System.err.println("Thread was interrupted while waiting for termination.");
e.printStackTrace();
}
}
}
Output:
Executing task 1 by pool-1-thread-1
Executing task 2 by pool-1-thread-2
Executing task 3 by pool-1-thread-1
Executing task 4 by pool-1-thread-2
Executing task 5 by pool-1-thread-1
Task 1 completed by pool-1-thread-1
Task 2 completed by pool-1-thread-2
Task 3 completed by pool-1-thread-1
Task 4 completed by pool-1-thread-2
Task 5 completed by pool-1-thread-1
All tasks completed successfully.
Example 3: Combining shutdownNow()
with awaitTermination()
In this example, we combine shutdownNow()
with awaitTermination()
to handle scenarios where we want to stop executing tasks immediately and wait for the completion of currently running tasks.
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
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) {
e.printStackTrace();
}
System.out.println("Task " + taskNumber + " completed by " + Thread.currentThread().getName());
});
}
// Shut down the executor immediately
List<Runnable> notExecutedTasks = executor.shutdownNow();
System.out.println("Tasks not executed: " + notExecutedTasks.size());
try {
// Wait for all currently running tasks to complete or timeout after 5 seconds
if (executor.awaitTermination(5, TimeUnit.SECONDS)) {
System.out.println("All running tasks completed successfully.");
} else {
System.out.println("Timeout elapsed before termination.");
}
} catch (InterruptedException e) {
System.err.println("Thread was interrupted while waiting for termination.");
e.printStackTrace();
}
}
}
Output:
Executing task 1 by pool-1-thread-1
Executing task 2 by pool-1-thread-2
Tasks not executed: 3
Task 1 completed by pool-1-thread-1
Task 2 completed by pool-1-thread-2
All running tasks completed successfully.
Conclusion
The ThreadPoolExecutor.awaitTermination()
method in Java is used for waiting for the completion of all tasks in the executor after a shutdown request. By using this method, you can ensure that your application properly waits for task completion before proceeding, helping to manage resources and maintain application stability.
Comments
Post a Comment
Leave Comment