如下爲我的的學習和總結,若是隻是爲了瞭解線程池,能夠谷歌到大量優秀的文章.這裏只是爲了記錄個人學習思路,參考的其餘人的博客.,有些概括不正確之處望斧正 我會不斷概括總結新看到的文章來豐富細節java
除了用線程池代碼看起來比較高大上這個理由外,先說說用線程池和不用線程池相比都有什麼好處吧 我就用大白話解釋了,總比複製粘貼死記硬背好些吧......數組
會用線程池不就得了?爲啥還要學那些亂七八糟的參數?賊複雜還很差背. 業務驅動技術,咱們在實際業務中可能須要到用到擁有不一樣特性的線程池.廢話很少說,先來DIY吧學習
數組結構
的有界阻塞隊列,此隊列按 FIFO
(先進先出)原則對元素進行排序。 LinkedBlockingQueue:一個基於鏈表結構
的阻塞隊列,此隊列按FIFO
(先進先出) 排序元素,吞吐量一般要高於ArrayBlockingQueue
。靜態工廠方法Executors.newFixedThreadPool()
使用了這個隊列。 SynchronousQueue:一個不存儲元素的阻塞隊列
。每一個插入操做必須等到另外一個線程調用移除操做,不然插入操做一直處於阻塞狀態
,吞吐量一般要高於LinkedBlockingQueue,靜態工廠方法Executors.newCachedThreadPool
使用了這個隊列。 SynchronousQueue沒有容納元素的能力,即它的isEmpty()方法老是返回true,可是給人的感受卻像是隻能容納一個元素。它模擬的功能相似於生活中一手交錢一手交貨這種情形 PriorityBlockingQueue:一個具備優先級的無限阻塞隊列。隊列滿了
,而且已建立的線程數小於最大線程數
,則線程池會再建立新的線程執行任務。值得注意的是若是使用了無界的任務隊列這個參數就沒什麼效果。隊列和線程池都滿了
,說明線程池處於飽和狀態,那麼必須採起一種策略處理提交的新任務。這個策略默認狀況下是AbortPolicy,表示沒法處理新任務時拋出異常。如下是JDK1.5提供的四種策略。 AbortPolicy(捨棄-拋出異常):直接拋出異常。 CallerRunsPolicy(調用者執行):只用調用者所在線程來運行任務。 DiscardOldestPolicy(丟棄最舊的):丟棄隊列裏最近的一個任務,並執行當前任務。 DiscardPolicy(丟棄):不處理,丟棄掉。 固然也能夠根據應用場景須要來實現RejectedExecutionHandler接口自定義策略。如記錄日誌或持久化不能處理的任務。參數比較多,但咱們要抓住重點去理解而不是死記硬背.線程池長啥樣?簡單描述就是個帶着個阻塞隊列的池子.固然它不是"死"的,它有本身解決特殊問題的各類的策略(飽和策略)線程
new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, milliseconds,runnableTaskQueue, handler);
rest
有兩種方式提交: execute 和 submit日誌
shutdown或shutdownNow方法來關閉線程池 原理是遍歷線程池中的工做線程,而後逐個調用線程的interrupt
方法來中斷線程,因此沒法響應中斷的任務可能永遠沒法終止。 shutdownNow首先將線程池的狀態設置成STOP
,而後嘗試中止全部的正在執行或暫停任務的線程,並返回等待執行任務的列表 shutdown只是將線程池的狀態設置成SHUTDOWN
狀態,而後中斷全部沒有正在執行任務的線程。code
線程池的處理流程以下:排序
首先線程池判斷基本線程池
是否已滿?沒滿,建立一個工做線程來執行任務。滿了,則進入下個流程。 其次線程池判斷工做隊列
是否已滿?沒滿,則將新提交的任務存儲在工做隊列裏。滿了,則進入下個流程。 最後線程池判斷整個線程池
是否已滿?沒滿,則建立一個新的工做線程來執行任務,滿了,則交給飽和策略
來處理這個任務。接口
經過線程池提供的參數進行監控。線程池裏有一些屬性在監控線程池的時候可使用 taskCount:線程池須要執行的任務數量。 completedTaskCount:線程池在運行過程當中已完成的任務數量。小於或等於taskCount。 largestPoolSize:線程池曾經建立過的最大線程數量。經過這個數據能夠知道線程池是否滿過。如等於線程池的最大大小,則表示線程池曾經滿了。 getPoolSize:線程池的線程數量。若是線程池不銷燬的話,池裏的線程不會自動銷燬,因此這個大小隻增不+ getActiveCount:獲取活動的線程數。生命週期