线程并发-ThreadPoolExcutor 原理实解
一、ThreadPoolExcutor 结构

二、源码分析
/*----------------------------1.提交任务----------------------------------*/ void execute(Runnable command): /*如果workerSet中工作线程数 小于 corePoolSize 则直接创建新的 Worker对象,并添加至 workerSet 中,然后启动 Worker对象 中的线程*/ if (workerCountOf(c) < corePoolSize) { if (addWorker(command, true)) return; c = ctl.get(); } /*如果 workerSet中线程 全部运行 且 线程数大于等于corePoolSize ,任务添加至阻塞队列workQueue*/ if (isRunning(c) && workQueue.offer(command)) { int recheck = ctl.get(); if (! isRunning(recheck) && remove(command)) reject(command); else if (workerCountOf(recheck) == 0) addWorker(null, false); } /*如果 workQueue 添加任务失败(队列已满),添加非核心线程。如果非核心线程添加失败(工作线程数wc >= maxinumPoolSize),则执行拒绝策略*/ else if (!addWorker(command, false)) reject(command); /*---------------------------- 2.添加任务&&创建线程----------------------------------*/ boolean addWorker(Runnable firstTask, boolean core): ... /** * 添加任务失败的情况: * 1. core=true:添加核心任务线程,如果当前工作线程数wc 大于等于 corePoolSize 则核心任务线程添加失败,返回false * 2. core=false: 添加非核心任务,如果工作线程数wc 大于等于 maxinumPoolSize 则非核心任务添加失败,返回false */ if (wc >= CAPACITY || wc >= (core ? corePoolSize : maximumPoolSize)) return false; ... /*创建新的Worker:新的线程和任务*/ w = new Worker(firstTask); final Thread t = w.thread; ... /*worker 添加到 workerSet*/ workers.add(w); ... /*启动worker 中的线程:线程启动后执行run()方法中的runWorker()方法*/ t.start(); /*----------------------------3.运行worker----------------------------------*/ final void runWorker(Worker w): /** * 创建的Worker线程在while循环中会不停的获取任务进行执行,直到获取的任务为空时循环结束,将线程从workerSet中移除,线程销毁。需注意以下情况: * 1. 设置keepAliveTime 超时时间的线程,在获取不到任务时返回null,则线程会终止(这种情况叫做非核心线程) * 2. 没有设置keepAliveTime 超时时间的线程会阻塞直到获得任务,所以会一直在 while循环中,不会退出(一遍情况叫做核心线程) */ try{ /* 不停的获取任务并进行执行,直到获取的任务为null */ while (task != null || (task = getTask()) != null) { ... task.run(); ... } }finally { /*获取到任务为 null 时进行线程清理工作:将当前worker从workerSet中移除,线程结束*/ processWorkerExit(w, completedAbruptly); } /*----------------------------4.worker运行中获取任务----------------------------------*/ Runnable getTask(): /** * ThreadPoolExcutor 中并未区分核心和非核心线程数,为了便于理解将 小于corePoolSize 时创建的线程叫核心线程,大于corePoolSize创建的线程叫非核心线程 * 线程是否空闲超时销毁: * 1.如果设置了 allowCoreThreadTimeOut=true ,则核心线程数也会超时销毁(workerSet集合中的Worker都相同) * 2.如果 allowCoreThreadTimeOut=false,则只有 大于corePoolSize的线程会超时销毁(获取任务时满足:wc > corePoolSize 条件时,获取任务为null 的线程就会销毁,可以认为是非核心线程) */ boolean timed = allowCoreThreadTimeOut || wc > corePoolSize; try { Runnable r = timed ? // 从队列中获取任务,超时则返回null(一般情况下将此处认为是非核心线程) workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : // 阻塞从队列中获取任务,直到获取成功为止(一般情况下将此处认为是核心线程,一直在不停的进行任务的获取和执行,不会销毁) workQueue.take(); if (r != null) return r; timedOut = true; } catch (InterruptedException retry) { timedOut = false; }
三、流程分析(待完善...)
本文来自博客园,作者:蓝迷梦,转载请注明原文链接:https://www.cnblogs.com/hewei-blogs/articles/17248188.html

浙公网安备 33010602011771号