线程池创建线程的逻辑图:
我们分析CachedThreadPool线程池里的线程是如何被回收的。
//Executors public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); } //ThreadPoolExecutor public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); }
牢牢记住CachedThreadPool的corePoolSize=0, maximumPoolSize=Integer.MAX_VALUE
工作线程的死循环:
//ThreadPoolExecutor final void runWorker(Worker w) { Thread wt = Thread.currentThread(); Runnable task = w.firstTask; w.firstTask = null; w.unlock(); // allow interrupts boolean completedAbruptly = true; try { while (task != null || (task = getTask()) != null) { w.lock(); if ((runStateAtLeast(ctl.get(), STOP) || (Thread.interrupted() && runStateAtLeast(ctl.get(), STOP))) && !wt.isInterrupted()) wt.interrupt(); try { beforeExecute(wt, task); Throwable thrown = null; 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 { processWorkerExit(w, completedAbruptly); } }
当工作线程第二次获取的task等于null时,线程将退出while循环,于是就死掉了。
//ThreadPoolExecutor private Runnable getTask() { // 标记poll()是否超时 boolean timedOut = false; retry: for (;;) { int c = ctl.get(); int rs = runStateOf(c); // Check if queue empty only if necessary. if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) { //工作线程数-1 decrementWorkerCount(); //返回null,工作线程将退出while循环,即线程会死掉 return null; } boolean timed; // Are workers subject to culling? for (;;) { int wc = workerCountOf(c); // allowCoreThreadTimeOut 默认为 false, newCachedThreadPool的corePoolSize为0 // 所以 timed = false || true,timed恒为true timed = allowCoreThreadTimeOut || wc > corePoolSize; // 对于newCachedThreadPool,wc 恒小于 maximumPoolSize // 第一次进for循环 true && !(false && true) = true // poll超时后,第二次进for循环 true && !(true && true) = false if (wc <= maximumPoolSize && ! (timedOut && timed)) break; if (compareAndDecrementWorkerCount(c)) //poll超时后,第二次进for循环, return null; c = ctl.get(); // Re-read ctl if (runStateOf(c) != rs) continue retry; // else CAS failed due to workerCount change; retry inner loop } try { //走poll分支 //poll会阻塞,直到有人调用workQueue.offer;或者超时返回null Runnable r = timed ? workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : workQueue.take(); if (r != null) return r; //超时 timedOut = true; } catch (InterruptedException retry) { timedOut = false; } } }
如图中所示:有2种情况会创建工作线程,1. 工作线程数小于corePoolSize;2. 入队失败,且工作线程数小于maximumPoolSize
//ThreadPoolExecutor 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(); } //对于CachedThreadPool,如果有工作线程在poll中阻塞,则入队成功 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); } //对于CachedThreadPool,如果没有工作线程在poll中阻塞,则入队失败 //初次调用execute,走这个分支,创建工作线程 else if (!addWorker(command, false)) reject(command); }
CachedThreadPool使用的是SynchronousQueue的
入队 :offer(E e)
出队:poll(long timeout, TimeUnit unit)
工作线程调用poll阻塞,等待timeout时间,如果超时,则返回null并回收线程;如果在等待期内,有任务入队,则成功返回任务,继续执行线程while循环。