這幾天主要是狂看源程式,在彌補了一些以前知識空白的同時,也學會了不少新的知識(比如 nio),或者稱為新技術吧。
線程池就是其中之一,一提到線程,我們會想到以前《作業系統》的生産者與消費者,信号量,同步控制等等。
一提到池,我們會想到資料庫連接配接池,但是線程池又如何呢?
建議:在閱讀本文前,先理一理同步的知識,特别是syncronized同步關鍵字的用法。
關于我對同步的認識,要緣于大三年的一本書,書名好像是 java 實戰,這本書寫得實在太妙了,真正的從理論到實踐,從截圖分析到.class位元組碼分析。哇,我想市場上很難買到這麼精緻的書了。作為一個java愛好者,我覺得絕對值得一讀。
我對此書印象最深之一的就是:equal()方法,由淺入深,經典!
還有就是同步了,其中提到了我的幾個程式設計誤區,以前如何使用同步提高性能等等,通過學習,使我對同步的認識進一步加深。
--------------------------------------------------------------------------------------------------
簡單介紹
建立線程有兩種方式:繼承thread或實作runnable。thread實作了runnable接口,提供了一個空的run()方法,是以不論是繼承thread還是實作runnable,都要有自己的run()方法。
一個線程建立後就存在,調用start()方法就開始運作(執行run()方法),調用wait進入等待或調用sleep進入休眠期,順利運作完畢或休眠被中斷或運作過程中出現異常而退出。
wait和sleep比較:
sleep方法有:sleep(long millis),sleep(long millis, long nanos),調用sleep方法後,目前線程進入休眠期,暫停執行,但該線程繼續擁有監視資源的所有權。到達休眠時間後線程将繼續執行,直到完成。若在休眠期另一線程中斷該線程,則該線程退出。
wait方法有:wait(),wait(long timeout),wait(long timeout, long nanos),調用wait方法後,該線程放棄監視資源的所有權進入等待狀态;
wait():等待有其它的線程調用notify()或notifyall()進入排程狀态,與其它線程共同争奪監視。wait()相當于wait(0),wait(0, 0)。
wait(long timeout):當其它線程調用notify()或notifyall(),或時間到達timeout亳秒,或有其它某線程中斷該線程,則該線程進入排程狀态。
wait(long timeout, long nanos):相當于wait(1000000*timeout + nanos),隻不過時間機關為納秒。
===================================================================================================
線程池:
多線程技術主要解決處理器單元内多個線程執行的問題,它可以顯著減少處理器單元的閑置時間,增加處理器單元的吞吐能力。
假設一個伺服器完成一項任務所需時間為:t1 建立線程時間,t2 線上程中執行任務的時間,t3 銷毀線程時間。
如果:t1 + t3 遠大于 t2,則可以采用線程池,以提高伺服器性能。
一個線程池包括以下四個基本組成部分:
1、線程池管理器(threadpool):用于建立并管理線程池,包括 建立線程池,銷毀線程池,添加新任務;
2、工作線程(poolworker):線程池中線程,在沒有任務時處于等待狀态,可以循環的執行任務;
3、任務接口(task):每個任務必須實作的接口,以供工作線程排程任務的執行,它主要規定了任務的入口,任務執行完後的收尾工作,任務的執行狀态等;
4、任務隊列(taskqueue):用于存放沒有處理的任務。提供一種緩沖機制。
線程池技術正是關注如何縮短或調整t1,t3時間的技術,進而提高伺服器程式性能的。它把t1,t3分别安排在伺服器程式的啟動和結束的時間段或者一些空閑的時間段,這樣在伺服器程式處理客戶請求時,不會有t1,t3的開銷了。
線程池不僅調整t1,t3産生的時間段,而且它還顯著減少了建立線程的數目,看一個例子:
假設一個伺服器一天要處理50000個請求,并且每個請求需要一個單獨的線程完成。線上程池中,線程數一般是固定的,是以産生線程總數不會超過線程池中線程的數目,而如果伺服器不利用線程池來處理這些請求則線程總數為50000。一般線程池大小是遠小于50000。是以利用線程池的伺服器程式不會為了建立50000而在處理請求時浪費時間,進而提高效率。
------------------------------------------------------------------------------
好了,廢話就到這裡了,下面就是程式了,我也不講解了,注釋已經很清晰了:
/** 線程池類,工作線程作為其内部類 **/
/** 任務接口類 **/