資源描述:
《【個(gè)人總結(jié)系列-42】線程池總結(jié)-學(xué)習(xí)-分析-實(shí)現(xiàn)-代碼分析》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在工程資料-天天文庫。
1、線程池總結(jié)-學(xué)習(xí)-分析-實(shí)現(xiàn)-代碼分析2.3.1線程池結(jié)構(gòu)分析在處理的各類問題及系統(tǒng)屮,經(jīng)常涉及到多線程編程的問題,如果每個(gè)任務(wù)來到以后系統(tǒng)都為它啟動(dòng)一個(gè)線程,那么這對(duì)服務(wù)的資源可能會(huì)造成很大的浪費(fèi),因?yàn)橥ǔG闆r下,創(chuàng)建線程是需要一定的開銷的,以時(shí)間為例,設(shè)創(chuàng)建線程的時(shí)間為T1,而任務(wù)接受后處理的吋間為T2,當(dāng)T1?T2時(shí),我們就應(yīng)當(dāng)考慮一種策略或者機(jī)制來控制,使得任務(wù)處理過程能在較低的功耗下完成。通常,我們可以用線程池來解決這個(gè)問題。首先,在服務(wù)啟動(dòng)的時(shí)候,我們可以啟動(dòng)好兒個(gè)線程,并用一個(gè)容器(如線程池)來管理這些線程。當(dāng)請(qǐng)求到來時(shí),可以從池小去-?個(gè)線程出來,執(zhí)行任務(wù)(通常是對(duì)請(qǐng)求的響應(yīng))
2、,當(dāng)任務(wù)結(jié)束后,再將這個(gè)線程放入池屮備用;如果請(qǐng)求到來而池屮沒有空閑的線程,該請(qǐng)求需要排隊(duì)等候。最后,當(dāng)服務(wù)關(guān)閉時(shí)銷毀該池即可。線程池屮通常由這樣幾個(gè)概念(接口)組成:?線程池(Threadpool):池是一個(gè)容器,容器中有很多個(gè)執(zhí)行器,每一個(gè)執(zhí)行器是一個(gè)線程。當(dāng)然,這個(gè)容器的實(shí)現(xiàn),可以是鏈表,可以是數(shù)組等等,不需要關(guān)心,需要關(guān)心的是,池必須捉供一個(gè)可以從屮取出執(zhí)行器的方法,可能還需要一個(gè)池中現(xiàn)有活動(dòng)線程數(shù)方法,銷毀池的方法等。?執(zhí)行器(Executor):每個(gè)執(zhí)行器是一個(gè)線程,每個(gè)執(zhí)行器可以執(zhí)行一個(gè)任務(wù),任務(wù)是做什么,此時(shí)還不很明確,它需要捉供任務(wù)的setter/getter方法,并且作為一
3、個(gè)線程,他可以獨(dú)立運(yùn)行,執(zhí)行器執(zhí)行完自身后,需要將自身放入池小。?任務(wù)(Task):任務(wù)是每個(gè)線程具體要做的事,它本身不能執(zhí)行,而需要將自身交給執(zhí)行器。整個(gè)池的機(jī)制和結(jié)構(gòu)就是這樣,當(dāng)然,需要一個(gè)調(diào)度者(scheduler)來協(xié)調(diào)主線程和池的關(guān)系。結(jié)構(gòu),或者接口的目的是為了讓我們從細(xì)節(jié)屮解脫出來,從一個(gè)比較抽象的層次來描述系統(tǒng),這樣的好處是簡單,而且設(shè)計(jì)出來的框架比較通用,可以適應(yīng)很多相近相似的情況。同步在線程并發(fā)屮意義非常大,對(duì)臨界資源的控制是并發(fā)時(shí)最關(guān)鍵的地方。如在線程池屮,當(dāng)池中沒有空閑的線程時(shí),新來的請(qǐng)求就必須等待,而一旦一個(gè)Task運(yùn)行結(jié)束后,一方面將自己放入池屮,一方面需要通知等待在
4、pool>
5、?的其他線程。每一個(gè)執(zhí)行器線程,一開始啟動(dòng),則進(jìn)入等待狀態(tài),此時(shí)不會(huì)消耗CPU資源。而當(dāng)在外部調(diào)用執(zhí)行器的startTask方法,即可通知線程從等待狀態(tài)中醒來,去出Task,執(zhí)行之,將執(zhí)行器本身放入池小,然后繼續(xù)等待。2.3.2線程池實(shí)現(xiàn)根據(jù)上面分析的線程池的功能和結(jié)構(gòu),整個(gè)線程池的類的結(jié)構(gòu)圖如卜?所示,主要包扌舌3個(gè)接口:Pool、Task和Executor,及相應(yīng)的實(shí)現(xiàn)。<>Pool0<>Task<>ExecutorGgetExecutor()QdeskoyO:void0execute():void0getRes
6、ultO:byte[]?5etTask(inUsk:Task):void0getTaskO:TaskGstartTask():voidAiAi<>圖線程池類圖結(jié)構(gòu)主要接口的定義如下所示:publicinterfacePool{//池接口ExecutorgetExecutor();voiddestroy();}publicinterfaceExecutor{//執(zhí)彳了器接丨IvoidsetTask(Tasktask);TaskgetTask();voidstartTask();}publicinterfaceTask{//這個(gè)接口也比較簡單,可以執(zhí)行,可以取到執(zhí)行結(jié)果voide
7、xecute();byte[]getResult();}線程池的實(shí)現(xiàn)如下所示,鑒于執(zhí)行器是池屮的對(duì)象,而且外部沒有必要知道其細(xì)節(jié),考慮將Executor接口的實(shí)現(xiàn)做為Pool接口的實(shí)現(xiàn)的內(nèi)部類,這樣做的另一個(gè)好處是,更便于池的管理。publicclassThreadPoolimplementsPool{privatebooleanisShut;privateLinkedListpool;privateintsize=3;publicThreadPool(){//readconfigurationandsetthe//contentofpoolbyobjectsofExecu
8、torisShut=false;//setthestatusofpooltomctivepool=newLinkedList();for(inti=0;i