【Java并发之执行器框架】 线程池

ThreadPoolExecutor

ThreadPoolExecutor 就是我们在并发和异步场景下,执行普通任务的线程池,下边我们来学习一下线程池的基本使用。

线程池的使用

public class ThreadPoolExecutor extends AbstractExecutorService {
    public static void main(String[] args) {
        // 核心线程数 1,最大线程数 1,存活时间 0,单位 s,无界队列
        ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0, SECONDS, new LinkedBlockingQueue<>());
        // 执行任务
        executor.execute(() -> {
            System.out.println("hello");
        });
        // 关闭线程池
        executor.shutdown();
        // 等待线程池终止s
        executor.awaitTerminal();
    }
}

源码分析

构造方法

public class Test {
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        // 校验参数
        if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0)
            throw new IllegalArgumentException();
        // 校验参数
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        // 初始化成员
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }
}
构造方法参数
参数描述可用参数
corePoolSize:int核心线程数,核心线程不会在任务队列没有任务时销毁-
maximumPoolSize:int最大线程数,任务队列满时创建线程执行任务-
keepAliveTime:long非核心线程存活时间-
unit:TimeUnit时间单位-
workQueue:BlockingQueue任务队列,当核心线程都在执行任务时,任务首先加入任务队列ArrayBlockingQueue
LinkedBlockingQueue
SynchronousQueue
PriorityBlockingQueue
threadFactory:ThreadFactory线程工厂,所有的工作线程都由线程工厂创建Executors.DefaultThreadFactory
自己实现
handler:RejectedExecutionHandler拒绝策略,任务队列已满,线程数已达到最大线程数AbortPolicy
CallerRunsPolicy
DiscardOldestPolicy
DiscardPolicy
自己实现

ThreadPoolExecutor 的基本数据结构

public class ThreadPoolExecutor extends AbstractExecutorService {
    // 原子整形,记录 ctl 值,ctl值包含运行状态和线程数
    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
    // 32 - 3 = 29
    private static final int COUNT_BITS = Integer.SIZE - 3;
    // 000_11111111111111111111111111111 低 29 位记录线程数
    private static final int COUNT_MASK = (1 << COUNT_BITS) - 1;
    /**
     * 高三位记录状态
     * 111_ 运行中,接受新任务并处理排队的任务
     * 000_ 关闭,不接受新任务,并且处理排队中的任务
     * 001_ 停止,不接受新任务,不处理队列中的任务,中断正在进行的任务
     * 010_ 清理,所有任务已经终止,线程数为 0,调用 terminated 方法
     * 011_ 终止,terminated 方法调用完成
     */
    private static final int RUNNING = -1 << COUNT_BITS;
    private static final int SHUTDOWN = 0 << COUNT_BITS;
    private static final int STOP = 1 << COUNT_BITS;
    private static final int TIDYING = 2 << COUNT_BITS;
    private static final int TERMINATED = 3 << COUNT_BITS;

    // 通过 ctl 值和掩码计算运行状态
    private static int runStateOf(int c) {
        return c & ~COUNT_MASK;
    }

    // 通过 ctl 值和掩码计算线程数
    private static int workerCountOf(int c) {
        return c & COUNT_MASK;
    }

    // RunningState 运行状态 和 WorkerCount 线程数计算 ctl
    private static int ctlOf(int rs, int wc) {
        return rs | wc;
    }

    // 比较运行状态
    private static boolean runStateLessThan(int c, int s) {
        return c < s;
    }

    private static boolean runStateAtLeast(int c, int s) {
        return c >= s;
    }

    // running状态为负数,不需要解码,直接比较即可
    private static boolean isRunning(int c) {
        return c < SHUTDOWN;
    }

    // 尝试原子性增加 ctl 线程数的值
    private boolean compareAndIncrementWorkerCount(int expect) {
        return ctl.compareAndSet(expect, expect + 1);
    }

    // 尝试原子性减少 ctl 线程数的值
    private boolean compareAndDecrementWorkerCount(int expect) {
        return ctl.compareAndSet(expect, expect - 1);
    }

    // 减 1 并获取 ctl 值
    private void decrementWorkerCount() {
        ctl.addAndGet(-1);
    }

    // 阻塞队列,没有空闲线程时存储任务
    private final BlockingQueue<Runnable> workQueue;
    // 重入锁
    private final ReentrantLock mainLock = new ReentrantLock();
    // 保存工作线程的集合
    private final HashSet<Worker> workers = new HashSet<>();
    // 通过 mainLock 创建条件变量,用于 awaitTerminated
    private final Condition termination = mainLock.newCondition();
    // 出现过的最大线程数
    private int largestPoolSize;
    // 处理完成的任务数
    private long completedTaskCount;
    /*
     * 所有用户控制的参数都用 volatile 修饰,保证可见性
     */
    // 线程工厂,所有的工作线程都从这里创建
    private volatile ThreadFactory threadFactory;
    // 拒绝策略,线程池饱和或关闭状态时调用这个接口
    private volatile RejectedExecutionHandler handler;
    // 线程存活时间,超时后线程会被回收
    private volatile long keepAliveTime;
    // 是否允许核心线程超时回收,默认为false
    private volatile boolean allowCoreThreadTimeOut;
    // 核心线程数,默认情况不会被回收
    private volatile int corePoolSize;
    // 最大线程数,任务队列满时会创建线程知道达到最大线程数
    private volatile int maximumPoolSize;
    // 默认拒绝策略,拒绝任务并抛异常
    private static final RejectedExecutionHandler defaultHandler =
            new AbortPolicy();

    // 调用shutdown的权限
    private static final RuntimePermission shutdownPerm =
            new RuntimePermission("modifyThread");
}

Worker

Worker 是线程池中工作线程类,分析一下代码

    // Worker 类继承了 AQS,所以具有同步器的特性,同时实现了 Runnable 接口
private final class Worker extends AbstractQueuedSynchronizer implements Runnable {
    private static final long serialVersionUID = 6138294804551838833L;
    // 这个工作线程类执行任务的线程对象,由 ThreadFactory 创建
    final Thread thread;
    // 初始化任务,可以为空
    Runnable firstTask;
    // 当前线程的完成任务数
    volatile long completedTasks;

    // 用初始化任务创建工作线程,可以为空
    Worker(Runnable firstTask) {
        // 设置AQS的state值,runWorker执行前不允许中断
        setState(-1);
        this.firstTask = firstTask;
        // 创建线程
        this.thread = getThreadFactory().newThread(this);
    }

    // 工作线程实现的 run 方法,实际逻辑在 runWorker 中
    public void run() {
        runWorker(this);
    }

    // 是否被占用
    protected boolean isHeldExclusively() {
        return getState() != 0;
    }

    // 重写 tryAcquire
    protected boolean tryAcquire(int unused) {
        if (compareAndSetState(0, 1)) {
            // 设置独占锁的线程
            setExclusiveOwnerThread(Thread.currentThread());
            return true;
        }
        return false;
    }

    // 重写 tryRelease
    protected boolean tryRelease(int unused) {
        setExclusiveOwnerThread(null);
        setState(0);
        return true;
    }

    public void lock() {
        acquire(1);
    }

    public boolean tryLock() {
        return tryAcquire(1);
    }

    public void unlock() {
        release(1);
    }

    public boolean isLocked() {
        return isHeldExclusively();
    }

    // 如果线程已经开始工作,就中断
    void interruptIfStarted() {
        Thread t;
        // 判断是否已经开始工作,并且没有被中断
        if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
            try {
                // 中断之
                t.interrupt();
            } catch (SecurityException ignore) {
            }
        }
    }
}

主要 API

方法简介
execute(Runnable):void执行任务
shutdown():void关闭线程池,拒绝新任务,继续处理剩余任务
shutdownNow():List立刻关闭线程池,返回剩余任务
awaitTermination(long, TimeUnit):boolean终止线程池,并带有超时时间
remove(Runnable):boolean移除任务
purge():void移除所有被取消(Future.cancel)的任务

下面我们来逐个方法进行分析

execute
public class ThreadPoolExecutor extends AbstractExecutorService {
    public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        // 获取当前线程池状态
        int c = ctl.get();
        // 从ctl中取出工作线程数,并和核心线程数进行比较 
        // 不足核心线程数,则添加新的工作线程来处理任务,结束
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            // 刷新 ctl 值
            c = ctl.get();
        }
        // 线程池正在运行,工作线程数已经达到核心线程数
        // 尝试将任务放到任务队列中
        // 继续判断是否要添加新的工作线程
        if (isRunning(c) && workQueue.offer(command)) {
            // 重新获取 ctl
            // 如果已经不处于运行状态,那么将任务移除,执行拒绝策略
            int recheck = ctl.get();
            if (!isRunning(recheck) && remove(command))
                reject(command);
                // 仍在运行中,并且工作线程数为0,添加新的非核心工作线程
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        // 队列满,直接添加工作线程,如果失败则拒绝
        else if (!addWorker(command, false))
            reject(command);
    }
}

这就是线程池的核心接口 execute 的源码,其中调用了 addWorker 和 reject 方法,下面来分析一下 addWorker 的源码

public class ThreadPoolExecutor extends AbstractExecutorService {
    // 添加工作线程
// firstTask: 初始任务
// core: 是否为核心线程
    private boolean addWorker(Runnable firstTask, boolean core) {
        retry:
        for (int c = ctl.get(); ; ) {
            // 判断是否处在 SHUTDOWN/STOP/TIDYING/TERMINATED 状态 并且
            // 如果处在 STOP 状态,初始任务为空,或者任务队列为空,则不创建
            // STOP及更高的状态,或者 SHUTDOWN 状态没有需要处理的任务,则不创建
            if (runStateAtLeast(c, SHUTDOWN)
                    && (runStateAtLeast(c, STOP) || firstTask != null || workQueue.isEmpty()))
                return false;
            for (; ; ) {
                // 已经超过核心线程数或最大线程数(通过core参数来判断)则不再添加工作线程
                if (workerCountOf(c) >= ((core ? corePoolSize : maximumPoolSize) & COUNT_MASK))
                    return false;
                // 尝试原子性增加工作线程数,成功则跳出 retry 代码块
                if (compareAndIncrementWorkerCount(c))
                    break retry;
                // 重新获取 ctl,cas操作
                c = ctl.get();
                // 处于 SHUTDOWN 以上状态则跳回retry
                if (runStateAtLeast(c, SHUTDOWN))
                    continue retry;
            }
        }
        // 线程数已经修改,还没有创建线程
        boolean workerStarted = false;
        boolean workerAdded = false;
        Worker w = null;
        try {
            // 初始化一个工作线程,执行构造方法的时候会锁定 worker 对象
            w = new Worker(firstTask);
            final Thread t = w.thread;
            if (t != null) {
                final ReentrantLock mainLock = this.mainLock;
                // 加锁,需要修改公共资源
                mainLock.lock();
                try {
                    // 获取 ctl
                    int c = ctl.get();
                    // 线程池状态为 RUNNING 或 状态为 SHUTDOWN 且 初始任务为空
                    if (isRunning(c) || (runStateLessThan(c, STOP) && firstTask == null)) {
                        // 线程状态不为 NEW 则抛出异常,此时start还未被调用
                        if (t.getState() != Thread.State.NEW)
                            throw new IllegalThreadStateException();
                        // 添加 worker
                        workers.add(w);
                        // 添加完成标记
                        workerAdded = true;
                        int s = workers.size();
                        // 更新线程池最大线程数
                        if (s > largestPoolSize)
                            largestPoolSize = s;
                    }
                } finally {
                    // 解锁
                    mainLock.unlock();
                }
                if (workerAdded) {
                    // 如果添加成功,则开启线程
                    t.start();
                    workerStarted = true;
                }
            }
        } finally {
            if (!workerStarted)
                // 添加线程失败
                addWorkerFailed(w);
        }
        return workerStarted;
    }
}

如果线程添加失败,则会调用 addWorkerFailed(Worker) 方法

public class ThreadPoolExecutor extends AbstractExecutorService {
    private void addWorkerFailed(Worker w) {
// 需要修改公共资源,所以要加锁
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            // 如果 w 存在,则将其移除
            if (w != null)
                workers.remove(w);
            // 还原工作线程数
            decrementWorkerCount();
            // 调用 tryTerminate,重新校验 ctl 状态,如果正在运行则直接返回
            tryTerminate();
        } finally {
            mainLock.unlock();
        }
    }
}
// 直接调用拒绝策略
public class ThreadPoolExecutor extends AbstractExecutorService {
    final void reject(Runnable command) {
        handler.rejectedExecution(command, this);
    }
}
runWorker

addWorker方法成功执行后,会添加一个工作线程到集合中,并调用该线程的start方法. 工作线程的主要逻辑在 runWorker 方法中实现,下面来分析一下runWorker方法的代码. 该方法是私有方法,但是非常重要,就单独介绍了.

public class ThreadPoolExecutor extends AbstractExecutorService {
    // 工作线程执行的核心逻辑
    final void runWorker(Worker w) {
        // 获取当前线程,即调用 runWorker 的 worker 线程
        Thread wt = Thread.currentThread();
        // 取出worker的初始化任务
        Runnable task = w.firstTask;
        // 清空初始化任务
        w.firstTask = null;
        w.unlock(); // 释放锁,允许中断,锁在初始化 Worker 的构造函数中加锁
        // 工作线程是否没有执行任务
        boolean completedAbruptly = true;
        try {
            // 获取任务
            while (task != null || (task = getTask()) != null) {
                // 加锁
                w.lock();
                // 如果状态在STOP\TIDY\TERMINATED 并且线程没有被中断
                // 中断线程
                if ((runStateAtLeast(ctl.get(), STOP) ||
                        (Thread.interrupted() &&
                                runStateAtLeast(ctl.get(), STOP))) &&
                        !wt.isInterrupted())
                    wt.interrupt();
                try {
                    // 执行前回调
                    beforeExecute(wt, task);
                    try {
                        // 执行任务
                        task.run();
                        // 执行完成后回调
                        afterExecute(task, null);
                    } catch (Throwable ex) {
                        // 执行完成后回调在异常情况下也会被调用
                        afterExecute(task, ex);
                        throw ex;
                    }
                } finally {
                    // 辅助 gc
                    task = null;
                    // 完成任务数增加
                    w.completedTasks++;
                    // 解锁,执行前加锁
                    w.unlock();
                }
            }
            completedAbruptly = false;
        } finally {
            // 工作线程退出
            processWorkerExit(w, completedAbruptly);
        }
    }
}

当工作线程开始运行后,会调用 runWorker 方法循环执行任务,runWorker 方法中会通过调用 getTask 方法来获取任务,下面分析一下 getTask 的代码

public class ThreadPoolExecutor extends AbstractExecutorService {
    private Runnable getTask() {
        // 执行poll方法是否带超时,默认为false
        boolean timedOut = false;
        for (; ; ) {
            int c = ctl.get();
            // 线程池处于 SHUTDOWN 状态(拒绝新任务),并且任务队列为空
            // 线程处于 STOP/TIDYING/TERMINATED 状态(拒绝新任务,并且不完成队列剩余任务)
            // 没有待执行的任务或不需要处理剩余任务,减少工作线程数,返回空,当前线程可以结束了
            if (runStateAtLeast(c, SHUTDOWN)
                    && (runStateAtLeast(c, STOP) || workQueue.isEmpty())) {
                decrementWorkerCount();
                return null;
            }
            int wc = workerCountOf(c);
            // 如果核心线程允许超时,则设置超时,如果核心线程不允许但工作线程数大于核心线程数(存在非核心线程)则设置超时
            // 如果当前存在非核心线程,如果没有任务,那么可以销毁非核心线程
            boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
            // 工作线程数大于最大线程数或者允许超时
            // 工作线程数大于 1 或者任务队列为空
            // 尝试减少工作线程数
            if ((wc > maximumPoolSize || (timed && timedOut))
                    && (wc > 1 || workQueue.isEmpty())) {
                if (compareAndDecrementWorkerCount(c))
                    return null;
                continue;
            }
            try {
                // 允许超时则超时调用poll,否则阻塞掉用take
                Runnable r = timed ?
                        workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                        workQueue.take();
                if (r != null)
                    return r;
                // 执行到这里说明等待超时,因为取出任务为空
                timedOut = true;
            } catch (InterruptedException retry) {
                timedOut = false;
            }
        }
    }
}

在工作线程结束之前会调用 processWorkerExit 方法来退出线程

public class ThreadPoolExecutor extends AbstractExecutorService {
    private void processWorkerExit(Worker w, boolean completedAbruptly) {
        // 如果异常退出
        if (completedAbruptly)
            // 直接减少工作线程数
            decrementWorkerCount();
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            // 完成任务数更新并移除工作线程
            completedTaskCount += w.completedTasks;
            workers.remove(w);
        } finally {
            mainLock.unlock();
        }
        // 调用 tryTerminate 检测运行状态
        tryTerminate();
        int c = ctl.get();
        // 如果线程池处于 Running 和 Shutdown 状态
        if (runStateLessThan(c, STOP)) {
            // 如果正常退出
            if (!completedAbruptly) {
                // 如果工作线程数满足最小需求线程数,则直接返回,否则添加工作线程
                // min设置为0或核心线程数,为了保证还有线程可以执行任务,所以设置为1 
                int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
                if (min == 0 && !workQueue.isEmpty())
                    min = 1;
                // 如果工作线程数超过最小线程数,则直接返回
                if (workerCountOf(c) >= min)
                    return;
            }
            // 添加
            addWorker(null, false);
        }
    }
}
shutdown

当我们需要关闭线程池时,则需要调用 shutdown 方法,下面来分析一下 shutdown 方法的代码。

public class ThreadPoolExecutor extends AbstractExecutorService {
    public void shutdown() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            // 校验权限
            checkShutdownAccess();
            // 设置状态为 SHUTDOWN
            advanceRunState(SHUTDOWN);
            // 中断所有空闲工作线程
            // 这里只会中断所有的空闲线程,而不会中断正在执行任务的线程
            interruptIdleWorkers();
            // 执行 onShutdown 回调
            onShutdown();
        } finally {
            mainLock.unlock();
        }
        // 尝试结束线程池
        tryTerminate();
    }
}

shutdown的过程就是首先将线程吃的状态设置为 SHUTDOWN,然后调用 interruptIdleWorkers 中断所有的空闲线程,最后执行 onShutdown 回调。 下面分析一下 interruptIdleWorkers
方法的代码。

public class ThreadPoolExecutor extends AbstractExecutorService {
    private void interruptIdleWorkers() {
        // 直接调用 interruptIdleWorkers,onlyOne传入false,代表中断所有空闲线程
        interruptIdleWorkers(false);
    }

    private void interruptIdleWorkers(boolean onlyOne) {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            for (Worker w : workers) {
                Thread t = w.thread;
                // 线程未被中断,并且尝试加锁成功(线程在执行任务前会加锁,加锁失败代表工作线程正在执行任务)
                if (!t.isInterrupted() && w.tryLock()) {
                    try {
                        // 中断
                        t.interrupt();
                    } catch (SecurityException ignore) {
                    } finally {
                        w.unlock();
                    }
                }
                // 如果只中断一个任务则跳出循环
                if (onlyOne)
                    break;
            }
        } finally {
            mainLock.unlock();
        }
    }
}

shutdown 方法最后会调用 tryTerminate 方法来尝试将线程池修改为 TERMINATED 状态,在上述一些方法中也会通过该方法来进行状态检测,下面来看一下具体实现

public class ThreadPoolExecutor extends AbstractExecutorService {
    final void tryTerminate() {
        for (; ; ) {
            int c = ctl.get();
            // 线程池处于 Running 直接返回
            // 线程池处于 TIDYING / TERMINATED 状态
            // 线程池处于 SHUTDOWN 状态,且任务队列非空,则需要处理队列中的任务,直接返回
            if (isRunning(c) ||
                    runStateAtLeast(c, TIDYING) ||
                    (runStateLessThan(c, STOP) && !workQueue.isEmpty()))
                return;
            // 仍然存在正在执行任务的工作线程
            if (workerCountOf(c) != 0) {
                // 中断空闲线程
                interruptIdleWorkers(ONLY_ONE);
                return;
            }
            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                // 将状态修改为 TIDYING,并调用 terminated 方法
                if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
                    try {
                        terminated();
                    } finally {
                        // 最后将状态修改为 TERMINATED
                        ctl.set(ctlOf(TERMINATED, 0));
                        // 唤醒所有等待线程池结束的线程
                        termination.signalAll();
                    }
                    return;
                }
            } finally {
                mainLock.unlock();
            }
        }
    }
}
shutdownNow

shutdown方法并不会立刻关闭线程池,而是拒绝新任务并等待队列中的任务处理完成,shutdownNow 方法可以直接将线程池设置为 STOP

public class ThreadPoolExecutor extends AbstractExecutorService {
    public List<Runnable> shutdownNow() {
        List<Runnable> tasks;
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            // 校验权限
            checkShutdownAccess();
            // 将状态设置为 STOP
            advanceRunState(STOP);
            // 中断所有工作线程
            interruptWorkers();
            // 将任务队列中的任务全部取出
            tasks = drainQueue();
        } finally {
            mainLock.unlock();
        }
        // 尝试结束线程池
        tryTerminate();
        return tasks;
    }

    private void interruptWorkers() {
        // 调用 Worker 的 interruptIfStarted 方法中断线程
        for (Worker w : workers)
            w.interruptIfStarted();
    }
}

然后是从任务队列中取出任务的 drainQueue 方法.

public class ThreadPoolExecutor extends AbstractExecutorService {
    private List<Runnable> drainQueue() {
        BlockingQueue<Runnable> q = workQueue;
        ArrayList<Runnable> taskList = new ArrayList<>();
        // 这是 BlockingQueue 接口提供的方法
        // 把队列中所有可用元素移除,并添加到参数传入的集合中
        q.drainTo(taskList);
        // 如果 q 还有留存任务
        if (!q.isEmpty()) {
            // 遍历队列,将剩余任务移除,并加入到 taskList 中
            for (Runnable r : q.toArray(new Runnable[0])) {
                if (q.remove(r))
                    taskList.add(r);
            }
        }
        return taskList;
    }
}
awaitTermination
public class ThreadPoolExecutor extends AbstractExecutorService {
    public boolean awaitTermination(long timeout, TimeUnit unit)
            throws InterruptedException {
        // 转为 ns
        long nanos = unit.toNanos(timeout);
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            // 如果工作在小于 TERMINATED 的状态,即非终止状态
            // 判断是否还有剩余等待时间,没有则返回 false
            // 否则调用条件变量 termination 的超时等待方法
            while (runStateLessThan(ctl.get(), TERMINATED)) {
                if (nanos <= 0L)
                    return false;
                nanos = termination.awaitNanos(nanos);
            }
            // 已经终止,返回 true
            return true;
        } finally {
            mainLock.unlock();
        }
    }
}
remove

可以用 remove 方法来移除任务

public class ThreadPoolExecutor extends AbstractExecutorService {
    public boolean remove(Runnable task) {
        // 任务队列删除指定 task
        boolean removed = workQueue.remove(task);
        // 检测 shutdown 状态和队列为空
        tryTerminate();
        // 返回被移除的任务
        return removed;
    }
}
purge

可以用 purge 方法来移除任务队列中所有已经被取消 (Future.cancel) 的任务

public class ThreadPoolExecutor extends AbstractExecutorService {
    public void purge() {
        final BlockingQueue<Runnable> q = workQueue;
        try {
            Iterator<Runnable> it = q.iterator();
            while (it.hasNext()) {
                Runnable r = it.next();
                // 判断是否被取消
                if (r instanceof Future<?> && ((Future<?>) r).isCancelled())
                    it.remove();
            }
        } catch (ConcurrentModificationException fallThrough) {
            // 如果发生了并发修改,则将队列元素放入数组,并重新对其进行移除
            for (Object r : q.toArray())
                if (r instanceof Future<?> && ((Future<?>) r).isCancelled())
                    q.remove(r);
        }
        // 检测 shutdown 和 队列为空
        tryTerminate();
    }
}

拒绝策略

AbortPolicy

AbortPolicy 是默认的拒绝策略

public static class AbortPolicy implements RejectedExecutionHandler {
    public AbortPolicy() {
    }

    // 直接抛出异常
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        throw new RejectedExecutionException("Task " + r.toString() +
                " rejected from " +
                e.toString());
    }
}
CallerRunsPolicy
    public static class CallerRunsPolicy implements RejectedExecutionHandler {
    public CallerRunsPolicy() {
    }

    // 如果线程池没有关闭,则直接在调用线程中执行任务
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        if (!e.isShutdown()) {
            r.run();
        }
    }
}
DiscardOldestPolicy
public static class DiscardOldestPolicy implements RejectedExecutionHandler {
    public DiscardOldestPolicy() {
    }

    // 从任务队列中弹出最老的任务,然后执行提交的任务
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        if (!e.isShutdown()) {
            e.getQueue().poll();
            e.execute(r);
        }
    }
}
DiscardPolicy
public static class DiscardPolicy implements RejectedExecutionHandler {
    public DiscardPolicy() {
    }

    // 不作任何处理
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值