Java ThreadPoolExecutor remove() Method

The ThreadPoolExecutor class in Java provides the remove(Runnable task) method to remove a specific task from the executor's internal queue. This guide will cover the usage of the remove(Runnable task) method, explain how it works, and provide concise examples to demonstrate its functionality in real-world use cases.

Introduction

The remove(Runnable task) method is used to remove a specific task from the ThreadPoolExecutor's internal queue. This method is useful when you want to cancel a task that has been submitted but not yet started.

remove Method Syntax

The syntax for the remove method is as follows:

public boolean remove(Runnable task)
  • The method takes a single parameter:
    • task - the Runnable task to be removed.
  • The method returns a boolean value:
    • true if the task was successfully removed from the queue.
    • false if the task could not be removed (e.g., if it has already started or completed).

Examples

Example 1: Basic Usage of remove(Runnable task)

In this example, we create a ThreadPoolExecutor, submit multiple tasks, and then remove a specific task from the queue using the remove(Runnable task) method.

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

public class RemoveTaskExample {
    public static void main(String[] args) {
        // Create a ThreadPoolExecutor with 2 threads
        ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);

        // Create a runnable task
        Runnable task1 = () -> {
            System.out.println("Executing task 1 by " + Thread.currentThread().getName());
            try {
                Thread.sleep(2000); // Simulate task execution
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Task 1 completed by " + Thread.currentThread().getName());
        };

        // Submit tasks to the executor
        executor.submit(task1);
        Runnable task2 = () -> {
            System.out.println("Executing task 2 by " + Thread.currentThread().getName());
            try {
                Thread.sleep(2000); // Simulate task execution
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Task 2 completed by " + Thread.currentThread().getName());
        };
        executor.submit(task2);

        Runnable task3 = () -> {
            System.out.println("Executing task 3 by " + Thread.currentThread().getName());
            try {
                Thread.sleep(2000); // Simulate task execution
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Task 3 completed by " + Thread.currentThread().getName());
        };
        executor.submit(task3);

        // Print the number of tasks in the queue before removal
        System.out.println("Queue size before removal: " + executor.getQueue().size());

        // Remove the task from the executor's queue
        boolean removed = executor.remove(task2);
        System.out.println("Task 2 removed: " + removed);

        // Print the number of tasks in the queue after removal
        System.out.println("Queue size after removal: " + executor.getQueue().size());

        // Shutdown the executor
        executor.shutdown();
    }
}

Output:

Queue size before removal: 2
Task 2 removed: true
Queue size after removal: 1
Executing task 1 by pool-1-thread-1
Executing task 3 by pool-1-thread-2
Task 1 completed by pool-1-thread-1
Task 3 completed by pool-1-thread-2

Example 2: Attempting to Remove a Running Task

In this example, we try to remove a task that has already started executing. The remove(Runnable task) method will return false because the task cannot be removed once it has started.

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

public class RemoveRunningTaskExample {
    public static void main(String[] args) {
        // Create a ThreadPoolExecutor with 1 thread
        ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(1);

        // Create a runnable task
        Runnable task1 = () -> {
            System.out.println("Executing task 1 by " + Thread.currentThread().getName());
            try {
                Thread.sleep(2000); // Simulate task execution
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Task 1 completed by " + Thread.currentThread().getName());
        };

        // Submit the task to the executor
        executor.submit(task1);

        // Attempt to remove the running task
        boolean removed = executor.remove(task1);
        System.out.println("Task 1 removed: " + removed);

        // Shutdown the executor
        executor.shutdown();
    }
}

Output:

Executing task 1 by pool-1-thread-1
Task 1 removed: false
Task 1 completed by pool-1-thread-1

Example 3: Removing a Task Before Execution

In this example, we submit multiple tasks to the ThreadPoolExecutor and remove a specific task that is still in the queue before it starts execution.

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

public class RemovePendingTaskExample {
    public static void main(String[] args) {
        // Create a ThreadPoolExecutor with 2 threads
        ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);

        // Create runnable tasks
        Runnable task1 = () -> {
            System.out.println("Executing task 1 by " + Thread.currentThread().getName());
            try {
                Thread.sleep(2000); // Simulate task execution
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Task 1 completed by " + Thread.currentThread().getName());
        };

        Runnable task2 = () -> {
            System.out.println("Executing task 2 by " + Thread.currentThread().getName());
            try {
                Thread.sleep(2000); // Simulate task execution
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Task 2 completed by " + Thread.currentThread().getName());
        };

        Runnable task3 = () -> {
            System.out.println("Executing task 3 by " + Thread.currentThread().getName());
            try {
                Thread.sleep(2000); // Simulate task execution
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Task 3 completed by " + Thread.currentThread().getName());
        };

        // Submit tasks to the executor
        executor.submit(task1);
        executor.submit(task2);
        executor.submit(task3);

        // Print the number of tasks in the queue before removal
        System.out.println("Queue size before removal: " + executor.getQueue().size());

        // Remove the task from the executor's queue
        boolean removed = executor.remove(task3);
        System.out.println("Task 3 removed: " + removed);

        // Print the number of tasks in the queue after removal
        System.out.println("Queue size after removal: " + executor.getQueue().size());

        // Shutdown the executor
        executor.shutdown();
    }
}

Output:

Queue size before removal: 1
Task 3 removed: true
Queue size after removal: 0
Executing task 1 by pool-1-thread-1
Executing task 2 by pool-1-thread-2
Task 1 completed by pool-1-thread-1
Task 2 completed by pool-1-thread-2

Conclusion

The ThreadPoolExecutor.remove(Runnable task) method in Java is used to remove specific tasks from the executor's internal queue before they start executing. By using this method, you can manage and control the tasks in the queue more effectively.

Comments