成功只有一個——按照本身的方式,去度過人生。面試
隨着cpu核數愈來愈多,不可避免的利用多線程技術以充分利用其計算能力。因此,多線程技術是服務端開發人員必須掌握的技術。多線程
線程的建立和銷燬,都涉及到系統調用,比較消耗系統資源,因此就引入了線程池技術,避免頻繁的線程建立和銷燬。工具
在Java中有一個Executors工具類,能夠爲咱們建立一個線程池,其本質就是new了一個ThreadPoolExecutor對象。線程池幾乎也是面試必考問題。本節結合源代碼,說說ThreadExecutor的工做原理spa
先看一下ThreadPoolExecutor參數最全的構造方法:線程
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { //... }
以上就是建立線程池時用到的參數,面試中常常會有面試官問到這個問題。3d
這裏用一個圖來講明線程池的執行流程
任務被提交到線程池,會先判斷當前線程數量是否小於corePoolSize,若是小於則建立線程來執行提交的任務,不然將任務放入workQueue隊列,若是workQueue滿了,則判斷當前線程數量是否小於maximumPoolSize,若是小於則建立線程執行任務,不然就會調用handler,以表示線程池拒絕接收任務。code
這裏以jdk1.8.0_111的源代碼爲例,看一下具體實現。對象
這塊代碼是在建立非核心線程時,即core等於false。判斷當前線程數是否大於等於maximumPoolSize,若是大於等於則返回false,即上邊說到的③中建立線程失敗的狀況。blog
addWorker方法的下半部分:
隊列
能夠看到在建立Worker時會調用threadFactory來建立一個線程。上邊的②中啓動一個線程就會觸發Worker的run方法被線程調用。
線程調用runWoker,會while循環調用getTask方法從workerQueue裏讀取任務,而後執行任務。只要getTask方法不返回null,此線程就不會退出。
若是當前線程數小於corePoolSize,則會調用workQueue的take方法阻塞在當前。