这可能是最简短的线程池分析文章了。
顶层设计,定义执行接口
Interface Executor(){ void execute(Runnable command); }
ExecutorService,定义控制接口
interface ExecutorService extends Executor{ }
抽象实现ExecutorService中的大部分方法
abstract class AbstractExecutorService implements ExecutorService{ //此处把ExecutorService中的提交方法都实现了 }
我们看下提交中的核心
public void execute(Runnable command) { if (command == null) throw new NullPointerException(); int c = ctl.get(); if (workerCountOf(c) < corePoolSize) { // ① //核心线程数没有满就继续添加核心线程 if (addWorker(command, true)) // ② return; c = ctl.get(); } if (isRunning(c) && workQueue.offer(command)) { // ③ int recheck = ctl.get(); if (! isRunning(recheck) && remove(command))// ④ reject(command); //⑦ else if (workerCountOf(recheck) == 0) // ⑤ //如果worker为0,则添加一个非核心worker,所以线程池里至少有一个线程 addWorker(null, false);// ⑥ } //队列满了以后,添加非核心线程 else if (!addWorker(command, false))// ⑧ reject(command);//⑦ }
这里就会有几道常见的面试题
1,什么时候用核心线程,什么时候启用非核心线程?
添加任务时优先使用核心线程,核心线程满了以后,任务放入队列中。只要队列不填满,就一直使用核心线程执行任务(代码①②)。
当队列满了以后开始使用增加非核心线程来执行队列中的任务(代码⑧)。
2,0个核心线程,2个非核心线程,队列100,添加99个任务是否会执行?
会执行,添加队列成功后,如果worker的数量为0,会添加非核心线程执行任务(见代码⑤⑥)
3,队列满了会怎么样?
队列满了,会优先启用非核心线程执行任务,如果非核心线程也满了,那就执行拒绝策略。
4,submit 和execute的区别是?
submit将执行任务包装成了RunnableFuture,最终返回了Future,executor 方法执行无返回值。
addworker实现
ThreadPoolExecutor extends AbstractExecutorService{ //保存所有的执行线程(worker) HashSet<Worker> workers = new HashSet<Worker>(); //存放待执行的任务,这块具体由指定的队列实现 BlockingQueue<Runnable> workQueue; public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler){ } //添加执行worker private boolean addWorker(Runnable firstTask, boolean core) { //这里每次都会基础校验和cas校验,防止并发无法创建线程, retry: for(;;){ for(;;){ if (compareAndIncrementWorkerCount(c)) break retry; c = ctl.get(); // Re-read ctl if (runStateOf(c) != rs) continue retry; } } try{ //创建一个worker w = new Worker(firstTask); final Thread t = w.thread; try{ //加锁校验,添加到workers集合中 workers.add(w); } //添加成功,将对应的线程启动,执行任务 t.start(); }finally{ //失败执行进行释放资源 addWorkerFailed(Worker w) } } //Worker 是对任务和线程的封装 private final class Worker extends AbstractQueuedSynchronizer implements Runnable{ //线程启动后会循环执行任务 public void run() { runWorker(this); } } //循环执行 final void runWorker(Worker w) { try{ while (task != null || (task = getTask()) != null) { //执行前的可扩展点 beforeExecute(wt, task); try{ //执行任务 task.run(); }finally{ //执行后的可扩展点,这块也把异常给吃了 afterExecute(task, thrown); } } //这里会对执行的任务进行统计 }finally{ //异常或者是循环退出都会走这里 processWorkerExit(w, completedAbruptly); } } //获取执行任务,此处决定runWorker的状态 private Runnable getTask() { //worker的淘汰策略:允许超时或者工作线程>核心线程 boolean timed = allowCoreThreadTimeOut || wc > corePoolSize; //满足淘汰策略且...,就返回null,交由processWorkerExit去处理线程 if ((wc > maximumPoolSize || (timed && timedOut)) && (wc > 1 || workQueue.isEmpty())) { if (compareAndDecrementWorkerCount(c)) return null; continue; } // 满足淘汰策略,就等一定的时间poll(),不满足,就一直<strong>本文来源gaodai#ma#com搞@@代~&码网</strong>等待take() Runnable r = timed ?workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :workQueue.take(); } //处理任务退出(循环获取不到任务的时候) private void processWorkerExit(Worker w, boolean completedAbruptly) { //异常退出的,不能调整线程数的 if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted decrementWorkerCount(); //不管成功或失败,都执行以下逻辑 //1,计数,2,减去一个线程 completedTaskCount += w.completedTasks; //将线程移除,并不关心是否非核心 workers.remove(w); //如果是还是运行状态 if (!completedAbruptly) { //正常终止的,处理逻辑 int min = allowCoreThreadTimeOut ? 0 : corePoolSize; //核心线程为0 ,最小值也是1 if (min == 0 && ! workQueue.isEmpty()) min = 1; //总线程数大于min就不再添加 if (workerCountOf(c) >= min) return; // replacement not needed } //异常退出一定还会添加worker,正常退出一般不会再添加线程,除非核心线程数为0 addWorker(null, false); } }