这个也比较容易,就是不断的从workQueue取任务,执行,直到没任务了跳出来。接下来就是worker如何被销毁的问题了
private void processWorkerExit(Worker w, boolean completedAbruptly) { if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted decrementWorkerCount(); final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { completedTaskCount += w.completedTasks; // 移除掉worker(裁员) workers.remove(w); } finally { mainLock.unlock(); } tryTerminate(); int c = ctl.get(); if (runStateLessThan(c, STOP)) { if (!completedAbruptly) { int min = allowCoreThreadTimeOut ? 0 : corePoolSize; if (min == 0 && ! workQueue.isEmpty()) min = 1; // 比核心线程数多的话,执行完的Worker直接移除就好 if (workerCountOf(c) >= min) return; // replacement not needed } // 小于核心线程数就会再加个Worker, 让他继续等待接收任务(招人) addWorker(null, false); } }直接从workers里边移除worker, 移除后如果worker数量比核心线程数还少,就再加个worker, 否则不加。
一些体会看源码一定不要过分纠结细节,就像这个线程池,我看网上很多文章去算那几个位运算的十进制数,感觉是在浪费时间,没有抓住重点。
当然这也不是绝对的(似乎说的矛盾了),一些细节的设计还是非常精妙值得学习的。还是这个位运算,为什么只用一个int表示线程池状态和worker的数量呢。
要多多联想,还是这个位运算,他是不是和读写锁用一个int既表示写状态又表示读状态十分相似。Worker继承AQS,是否能让你想起AQS的种种。
总之,个人觉得第一遍看是一定不能沉溺于细节的,他会让你迷惘和丧失信心;第二遍、第三遍可以关注一下细节,感受大师级的设计的美妙之处。当然笔者仅仅粗略看了一遍(逃~)
最后大雄五一假期阅读了《java并发编程艺术》这本书,整理了一本gitbook笔记(还没写完),需要的同学可以扫描文末二维码关注“大雄和你一起学编程”公众号,后台回复我爱java领取。这本gitbook还没彻底完成,所以可能还有些小错误。未来会大约每两天推送其中的一篇文章。
如下是这本gitbook的目录截图