首页 > 学院 > 开发设计 > 正文

《java.util.concurrent 包源码阅读》12 线程池系列之ThreadPoolExecutor 第二部分

2019-11-14 20:54:00
字体:
来源:转载
供稿:网友
java.util.concurrent 包源码阅读》12 线程池系列之ThreadPoolExecutor 第二部分

接着说worker线程是如何工作的。ThreadPoolExecutor有一个成员类叫Worker,所起到的作用就是线程池worker线程的作用。

PRivate final class Worker extends AbstractQueuedSynchronizer implements Runnable

这里AbstractQueuedSynchronizer的作用是使Worker具有锁的功能,在执行任务时,会把Worker锁住,这个时候就无法中断Worker。Worker空闲时候是线程池可以通过获取锁,改变Worker的某些状态,在此期间因为锁被占用,Worker就是不会执行任务的。

Worker工作的逻辑在ThreadPoolExecutor#runWorker方法中

        public void run() {            runWorker(this);        }

因此转到runWorker方法:

    final void runWorker(Worker w) {        Runnable task = w.firstTask;        w.firstTask = null;        boolean completedAbruptly = true;        try {            // 执行分配的任务或者从BlockingQueue中等待获取任务            while (task != null || (task = getTask()) != null) {                w.lock();                clearInterruptsForTaskRun();                try {                    // 执行任务之前的工作                    beforeExecute(w.thread, task);                    Throwable thrown = null;                    // 执行任务,如果发生异常,该Worker就不会再继续执行任务                    try {                        task.run();                    } catch (RuntimeException x) {                        thrown = x; throw x;                    } catch (Error x) {                        thrown = x; throw x;                    } catch (Throwable x) {                        thrown = x; throw new Error(x);                    } finally {                        // 任务执行完的工作                        afterExecute(task, thrown);                    }                } finally {                    task = null;                    w.completedTasks++;                    w.unlock();                }            }            completedAbruptly = false;        } finally {            // Worker不再执行任务的处理,completedAbruptly为false            // 表示正常结束,否则表示执行任务出错。            processWorkerExit(w, completedAbruptly);        }    }

来看看processWorkerExit,重点看看执行任务发生异常时该如何处理

    private void processWorkerExit(Worker w, boolean completedAbruptly) {        // 发生异常,首先要更新Worker数量        if (completedAbruptly)            decrementWorkerCount();        // 移除这个Worker        final ReentrantLock mainLock = this.mainLock;        mainLock.lock();        try {            completedTaskCount += w.completedTasks;            workers.remove(w);        } finally {            mainLock.unlock();        }        // 尝试停止线程池,正常运行的线程池调用该方法不会有任何动作        tryTerminate();        int c = ctl.get();        // 如果线程池没有被关闭的话,        if (runStateLessThan(c, STOP)) {            // Worker不是异常退出,检查worker线程数是不是小于最小值            // 这个最小值分为几种情况:            // 1. allowCoreThreadTimeOut(JDK6新加)表示是否允许线程池在超            //     过一定时间没有收到任务后退出,这种情况下,最小值为0,因为如果如            //     果一直没有任何任务,worker线程数是0            // 2. 最小值为corePoolSize,因为corePoolSize可能为0,因此这种情况            //     下,如果有任务的话必然会有Worker,因此最小值为1            if (!completedAbruptly) {                int min = allowCoreThreadTimeOut ? 0 : corePoolSize;                if (min == 0 && ! workQueue.isEmpty())                    min = 1;                if (workerCountOf(c) >= min)                    return;            }            // 如果Worker线程数小于最小值,新建一个Worker线程            addWorker(null, false);        }    }

这篇文章主要讲述了Worker线程的工作原理,接下里会讲线程池是如何进行状态切换的。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表