【視聽盛宴】Java線程池(2013.8.28)

公司組織了一場關於Java線程池的講座,我對Java不甚瞭解,對Java線程池就更不知道了。根據演講的PPT,加上自己的理解寫成了這篇文章,其中不免有錯誤的地方,還望大家指正。


使用Java線程池的優點

當我們使用單線程時,不僅處理速度慢,而且極不安全,試想,如果這條線程由於某些原因而掛掉,將導致下面所有的任務都沒法完成,Java線程池的使用就規避了這樣的風險,而且也提供了系統資源的利用率,具體來說,使用Java線程池有如下三個優點:

  1. 提供系統穩定性,避免一個線程的掛掉而影響到整個系統
  2. 重複利用已創建的線程,不僅降低了反覆創建和銷燬線程造成的資源消耗,也提高了系統的響應時間
  3. 對線程進行統一管理,提高線程的可管理性

創建Java線程池語句

創建Java線程池的語句如下:

new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, timeUnit,runnableTaskQueue, rejectedExecutionHandler);

要理解其中參數的意義,先來看一下Java線程池處理新任務的基本流程是怎樣的,如下圖:


我們根據上面的流程逐一介紹這些參數。當用戶提交一個新任務時,Java線程池首先判斷池中的存活線程數是否大於corePoolSize(Java線程池中最小存活線程數),若不大於,則直接創建一個新的線程來執行這個任務,而不管現有線程是否空閒;若大於,則判斷runnableTaskQueue(由等待執行的任務組成的阻塞隊列)是否達到了阻塞的最大值,若小於,則將該任務放在runnableTaskQueue中;若大於,則判斷Java線程池中存活的線程數是否大於maximumPoolSize(Java線程池中最大存活線程數),若小於,則創建一個新的線程來執行這個任務(此時,無空閒線程,如有空閒線程則直接用空閒線程執行);若大於,則按照rejectedExecutionHandler(飽和策略)處理提交的新任務。

其中runnableTaskQueue可以採用不同的策略存儲任務,學過操作系統的人應該對這些策略很熟悉,在這就不具體介紹了。而JDK1.5提供了四種rejectedExecutionHandler策略:

1.    AbortPolicy:直接拋出異常

2.    DiscardPolicy:不處理,直接丟棄

3.    CallerRunsPolicy:只用調用者所在線程來執行任務

4.    DiscardPolicy:丟棄阻塞隊列裏最新提交的任務,同時執行當前任務

也可以自定義rejectedExecutionHandler策略。

除了上面介紹的四個參數外還有兩個參數:keepAliveTime,和timeUnit,這兩個參數用來控制線程的存活時間,第一個是數值,第二個是單位。

向Java線程池提交任務

向Java線程池提交任務有兩種方法:execute和submit,兩者的區別是前者沒有返回值,而後者有。

關閉Java線程池

關閉Java線程池也有兩種方法:shutdown和shutdownNow,前者會等待正在執行的任務執行完畢再關閉Java線程池,而後者直接關閉Java線程池,從而會導致所有任務中斷。

監控Java線程池常用的屬性

我們可以通過監控Java線程池的屬性來查看Java線程池的運行狀態,從而更有效的配置Java線程池,可監控的屬性如下:

  1. taskCount:Java線程池需要執行的任務數量,採用累加
  2. completedTaskCount: Java線程池在運行過程中已完成的任務數量
  3. largestPoolSize: Java線程池曾創建過的最大線程數
  4. getPoolSize:得到Java線程池的線程數量
  5. getActiveCount:獲得活動的線程數

最後,還是要申明一點,這篇文章是在對Java不熟悉的情況下寫的,肯定會有理解錯誤的地方,歡迎大家批評指教!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章