Java并发编程高级篇(十一):执行器之处理被拒绝的任务

我们知道在调用执行器的shutdown()方法后,再向执行器提交任务会被拒绝。执行器框架为我们提供了一个类RejectedExecutionHandler,来让我们自定义一些被拒绝任务的处理逻辑。

首先实现自定义的拒绝任务处理逻辑,继承RejectedExecutionHandler,并实现rejectedExecution方法。

import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 创建执行器拒绝任务处理器
 *
 * Created by hadoop on 2016/11/3.
 */
public class RejectedTaskController implements RejectedExecutionHandler {
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        System.out.printf("RejectedTaskController: The task %s has been rejected.\n", r.toString());
        System.out.printf("RejectedTaskController: Executor is %s\n", executor.toString());
        System.out.printf("RejectedTaskController: Executor terminating: %s\n", executor.isTerminating());
        System.out.printf("RejectedTaskController: Executor terminated: %s\n", executor.isTerminated());
    }
}

模拟一个任务线程,实现Runnable接口。

import java.util.concurrent.TimeUnit;

/**
 *
 * Created by hadoop on 2016/11/3.
 */
public class Task implements Runnable {
    private String name;

    public Task(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        long duration = (long)(Math.random() * 10);

        System.out.printf("Task: %s will run during %d seconds\n", name, duration);

        try {
            TimeUnit.SECONDS.sleep(duration);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public String toString() {
        return this.name;
    }
}

在主线程类中,首先初始化自定义的被拒绝任务处理器,然后把它赋值给执行器。模拟在shutdown()方法后提交任务,并观察结果。

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

/**
 * 处理在执行器中被拒绝的任务
 *
 * 我们使用shutdown方法来关闭执行器,但是如果当前有正在执行的任务,执行器会等待任务执行完成才会关闭。
 * 但这个时候执行期已经不再接受任何任务了,我们发送任务给执行器会被拒绝。
 * ThreadPoolExecutor提供了一套机制了处理这些被拒绝的任务。
 *
 * 我们定义了一个执行器拒绝任务储丽丽RejectedTaskController.
 * 在方法rejectedExecution(Runnable r, ThreadPoolExecutor executor)中处理被拒绝的任务。
 *
 * 需要通过执行器的setRejectedExecutionHandler(controller)方法来给执行器设置决绝任务处理器类。
 *
 * 当有任务发送给处理器的时候,会检查处理器是否被shutdown,如果shutdown那么就会调用拒绝任务处理器。
 * 如果没有定义这个拒绝任务处理器,那么就会抛出RejectedExecutionException异常。
 *
 * Created by hadoop on 2016/11/3.
 */
public class Main {
    public static void main(String[] args) {
        ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();

        RejectedTaskController controller = new RejectedTaskController();

        executor.setRejectedExecutionHandler(controller);

        for (int i = 0; i < 3; i++) {
            Task task = new Task("Task" + i);
            executor.submit(task);
        }

        executor.shutdown();

        Task task = new Task("RejectTask");
        executor.submit(task);
    }
}

控制台结果:

RejectedTaskController: The task java.util.concurrent.FutureTask@5d86aad9 has been rejected.
Task: Task1 will run during 2 seconds
Task: Task0 will run during 0 seconds
Task: Task2 will run during 8 seconds
RejectedTaskController: Executor is java.util.concurrent.ThreadPoolExecutor@767ca7f0[Shutting down, pool size = 3, active threads = 3, queued tasks = 0, completed tasks = 0]
RejectedTaskController: Executor terminating: true
RejectedTaskController: Executor terminated: false

你可能感兴趣的:(Java并发编程高级篇(十一):执行器之处理被拒绝的任务)