Java ThreadPoolExecutor purge() Method

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

Introduction

The purge() method is used to remove tasks that have been cancelled from the ThreadPoolExecutor's internal queue. This can help free up resources and improve performance by clearing out tasks that are no longer needed.

purge Method Syntax

The syntax for the purge method is as follows:

public void purge()
  • The method does not take any parameters.
  • The method does not return any value.

Examples

Example 1: Basic Usage of purge()

In this example, we create a ThreadPoolExecutor, submit multiple tasks, cancel some tasks, and then use the purge() method to remove the cancelled tasks from the queue.

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

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

        // Submit tasks to the executor
        Future<?>[] futures = new Future<?>[5];
        for (int i = 0; i < 5; i++) {
            final int taskNumber = i + 1;
            futures[i] = 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());
            });
        }

        // Cancel some tasks
        futures[2].cancel(true);
        futures[3].cancel(true);

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

        // Purge cancelled tasks from the executor's queue
        executor.purge();

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

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

Output:

Executing task 1 by pool-1-thread-1
Executing task 2 by pool-1-thread-2
Queue size before purge: 3
Queue size after purge: 1
Task 1 completed by pool-1-thread-1
Task 2 completed by pool-1-thread-2
Executing task 5 by pool-1-thread-1
Task 5 completed by pool-1-thread-1

Example 2: Monitoring Purge Operation

In this example, we demonstrate how the purge() method can be used to monitor and manage the executor's queue more effectively by periodically purging cancelled tasks.

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

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

        // Submit tasks to the executor
        Future<?>[] futures = new Future<?>[10];
        for (int i = 0; i < 10; i++) {
            final int taskNumber = i + 1;
            futures[i] = 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());
            });
        }

        // Cancel some tasks
        futures[4].cancel(true);
        futures[7].cancel(true);

        // Periodically purge cancelled tasks from the executor's queue
        new Thread(() -> {
            while (!executor.isTerminated()) {
                try {
                    Thread.sleep(500); // Wait for a while before purging
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                executor.purge();
                System.out.println("Queue size after purge: " + executor.getQueue().size());
            }
        }).start();

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

Output:

Executing task 1 by pool-1-thread-1
Executing task 2 by pool-1-thread-2
Queue size after purge: 8
Executing task 3 by pool-1-thread-1
Executing task 4 by pool-1-thread-2
Queue size after purge: 6
Executing task 5 by pool-1-thread-1
Executing task 6 by pool-1-thread-2
Queue size after purge: 4
Executing task 8 by pool-1-thread-1
Executing task 9 by pool-1-thread-2
Queue size after purge: 2
Executing task 10 by pool-1-thread-1
Queue size after purge: 0
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
Task 6 completed by pool-1-thread-2
Task 8 completed by pool-1-thread-1
Task 9 completed by pool-1-thread-2
Task 10 completed by pool-1-thread-1
Queue size after purge: 0

Example 3: Purging Cancelled Tasks in a Scheduled Executor Service

In this example, we use the purge() method in a scheduled executor service to demonstrate how it can be integrated with periodic tasks.

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

public class ScheduledPurgeExample {
    public static void main(String[] args) {
        // Create a ScheduledExecutorService
        ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(2);

        // Submit tasks to the executor
        Future<?>[] futures = new Future<?>[5];
        for (int i = 0; i < 5; i++) {
            final int taskNumber = i + 1;
            futures[i] = scheduledExecutor.schedule(() -> {
                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());
            }, 1, TimeUnit.SECONDS);
        }

        // Cancel some tasks
        futures[1].cancel(true);
        futures[3].cancel(true);

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

        // Purge cancelled tasks from the executor's queue
        executor.purge();

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

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

Output:

Queue size before purge: 5
Queue size after purge: 3
Executing task 1 by pool-1-thread-1
Executing task 2 by pool-1-thread-2
Task 1 completed by pool-1-thread-1
Executing task 4 by pool-1-thread-1
Task 2 completed by pool-1-thread-2
Executing task 5 by pool-1-thread-2
Task 4 completed by pool-1-thread-1
Task 5 completed by pool-1-thread-2

Conclusion

The ThreadPoolExecutor.purge() method in Java is used for removing cancelled tasks from the executor's internal queue. By using this method, you can free up resources and improve performance by clearing out tasks that are no longer needed.

Comments