




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
本文格式為Word版,下載可任意編輯——Java多線程的開(kāi)發(fā)技巧Java多線程的開(kāi)發(fā)技巧
導(dǎo)語(yǔ):好多開(kāi)發(fā)者談到Java多線程開(kāi)發(fā),僅僅停留在newThread….start或直接使用Executor框架這個(gè)層面,對(duì)于線程的管理和操縱卻不夠深入,下面是Java多線程的開(kāi)發(fā)技巧,一起來(lái)學(xué)習(xí)下吧:
不使用線程池的缺點(diǎn)
有些開(kāi)發(fā)者圖省事,遇到需要多線程處理的地方,直接newThread….start,對(duì)于一般場(chǎng)景是沒(méi)問(wèn)題的,但假設(shè)是在并發(fā)苦求很高的處境下,就會(huì)有些隱患:
1.新建線程的開(kāi)銷(xiāo)。線程雖然比進(jìn)程要輕量大量,但對(duì)于JVM來(lái)說(shuō),新建一個(gè)線程的代價(jià)還是挺大的,決不同于新建一個(gè)對(duì)象。
2.資源消耗量。沒(méi)有一個(gè)池來(lái)限制線程的數(shù)量,會(huì)導(dǎo)致線程的數(shù)量直接取決于應(yīng)用的并發(fā)量,這樣有潛在的線程數(shù)據(jù)巨大的可能,那么資源消耗量將是巨大的。
3.穩(wěn)定性。當(dāng)線程數(shù)量超過(guò)系統(tǒng)資源所能承受的程度,穩(wěn)定性就會(huì)成問(wèn)題。
制定執(zhí)行策略
在每個(gè)需要多線程處理的地方,不管并發(fā)量有多大,需要考慮線程的執(zhí)行策略:
1.任務(wù)以什么依次執(zhí)行
2.可以有多少個(gè)任務(wù)并發(fā)執(zhí)行
3.可以有多少個(gè)任務(wù)進(jìn)入等待執(zhí)行隊(duì)列
4.系統(tǒng)過(guò)載的時(shí)候,理應(yīng)放棄哪些任務(wù)?如何通知到應(yīng)用程序?
5.一個(gè)任務(wù)的執(zhí)行前后理應(yīng)做什么處理
線程池的類(lèi)型
不管是通過(guò)Executors創(chuàng)造線程池,還是通過(guò)Spring來(lái)管理,都得領(lǐng)會(huì)知道有哪幾種線程池:
FixedThreadPool:定長(zhǎng)線程池,提交任務(wù)時(shí)創(chuàng)造線程,直到池的最大容量,假設(shè)有線程非預(yù)期終止,會(huì)補(bǔ)充新線程
CachedThreadPool:可變線程池,它猶如一個(gè)彈簧,假設(shè)沒(méi)有任務(wù)需求時(shí),它回收空閑線程,假設(shè)需求增加,那么按需增加線程,不對(duì)池的大小做限制
SingleThreadExecutor:?jiǎn)尉€程。處理不過(guò)來(lái)的任務(wù)會(huì)進(jìn)入FIFO隊(duì)列等待執(zhí)行
SecheduledThreadPool:周期性線程池。支持執(zhí)行周期性線程任務(wù)
其實(shí),這些不同類(lèi)型的線程池都是通過(guò)構(gòu)建一個(gè)ThreadPoolExecutor來(lái)完成的,所不同的是corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueue,threadFactory這么幾個(gè)參數(shù)。概括可以參見(jiàn)JDKDOC。
線程池飽和策略
由以上線程池類(lèi)型可知,除了CachedThreadPool其他線程池都有飽和的可能,當(dāng)飽和以后就需要相應(yīng)的策略處理苦求線程的任務(wù),ThreadPoolExecutor采取的方式通過(guò)隊(duì)列來(lái)存儲(chǔ)這些任務(wù),當(dāng)然會(huì)根據(jù)池類(lèi)型不同選擇不同的隊(duì)列,譬如FixedThreadPool和SingleThreadExecutor默認(rèn)采用的是無(wú)限長(zhǎng)度的LinkedBlockingQueue。但從系統(tǒng)可控性講,最好的做法是使用定長(zhǎng)的ArrayBlockingQueue或有限的LinkedBlockingQueue,并且當(dāng)達(dá)成上限時(shí)通過(guò)ThreadPoolExecutor.setRejectedExecutionHandler方法設(shè)置一個(gè)拒絕任務(wù)的策略,JDK供給了AbortPolicy、CallerRunsPolicy、DiscardPolicy、DiscardOldestPolicy幾種策略,概括差異可見(jiàn)JDKDOC
線程無(wú)憑借性
多線程任務(wù)設(shè)計(jì)上盡量使得各任務(wù)是獨(dú)立無(wú)憑借的,所謂憑借性可兩個(gè)方面:
線程之間的憑借性。假設(shè)線程有憑借可能會(huì)造成死鎖或饑餓
調(diào)用者與線程的憑借性。調(diào)用者得監(jiān)視線程的完成處境,影響可并發(fā)量
當(dāng)然,在有些業(yè)務(wù)里切實(shí)需要確定的憑借性,譬如調(diào)用者需要得到線程完成后結(jié)果,傳統(tǒng)的'Thread是不便完成的,由于run方法無(wú)返回值,只能通過(guò)一些共享的變量來(lái)傳遞結(jié)果,但在Executor框架里可以通過(guò)Future和Callable實(shí)現(xiàn)需要有返回值的任務(wù),當(dāng)然線程的異步性導(dǎo)致需要有相應(yīng)機(jī)制來(lái)保證調(diào)用者能等待任務(wù)完成,關(guān)于Future和Callable的用法見(jiàn)下面的實(shí)例就一目了然了:
01publicclassFutureRenderer
02privatefinalExecutorServiceexecutor=...;
03voidrenderPageCharSequencesource
04finalListimageInfos=scanForImageInfosource;
05Callablelisttask=
06newCallablelist
07publicListcall
08Listresult
09=newArrayList;
10forImageInfoimageInfo:imageInfos
11result.addimageInfo.downloadImage;
12returnresult;
13
14;
15Futurelistfuture=executor.submittask;
16renderTextsource;
17try
18ListimageData=future.get;
19forImageDatadata:imageData
20renderImagedata;
21catchInterruptedExceptione
22//Re-assertthethreadsinterruptedstatus
23Thread.currentTerrupt;
24//Wedontneedtheresult,socancelthetasktoo
25future.canceltrue;
26catchExecutionExceptione
27throwlaunderThrowablee.getCause;
28
29
30
以上代碼關(guān)鍵在于ListimageData=future.get;假設(shè)Callable類(lèi)型的任務(wù)沒(méi)有執(zhí)行完時(shí),調(diào)用者會(huì)阻塞等待。不過(guò)這樣的方式還是得精心使用,很輕易造成不良設(shè)計(jì)。另外對(duì)于這種需要等待的場(chǎng)景,就需要設(shè)置一個(gè)最大容忍時(shí)間timeout,設(shè)置方法可以在future.get加上timeout參數(shù),或是再調(diào)用ExecutorService.invokeAll加上timeout參數(shù)
線程的取消與關(guān)閉
一般的處境下是讓線程運(yùn)行完成后自行關(guān)閉,但有些時(shí)候也會(huì)中途取消或關(guān)閉線程,譬如以下處境:
調(diào)用者強(qiáng)制取消。譬如一個(gè)長(zhǎng)時(shí)間運(yùn)行的任務(wù),用戶點(diǎn)擊”cancel”按鈕強(qiáng)行取消
限時(shí)任務(wù)
發(fā)生不成處理的任務(wù)
整個(gè)應(yīng)用程序或服務(wù)的關(guān)閉
因此需要有相應(yīng)的取消或關(guān)閉的方法和策略來(lái)操縱線程,一般有以下方法:
1通過(guò)變量標(biāo)識(shí)來(lái)操縱
這種方式對(duì)比老土,但使用得分外廣泛,主要缺點(diǎn)是對(duì)有阻塞的操作操縱不好,代碼例如如下所示:
01publicclassPrimeGeneratorimplementsRunnable
02@GuardedBythis
03privatefinalListprimes
04=newArrayList;
05privatevolatilebooleancancelled;
06publicvoidrun
07BigIntegerp=BigInteger.ONE;
08while!cancelled
09p=p.nextProbablePrime;
10synchronizedthis
11primes.addp;
12
13
14
15publicvoidcancelcancelled=true;
16publicsynchronizedListget
17returnnewArrayListprimes;
18
19
2中斷
中斷通常是實(shí)現(xiàn)取消最明智的選擇,但線程自身需要支持中斷處理,并且要處理好中斷策略,一般響應(yīng)中斷的方式有兩種:
處理完中斷清理后持續(xù)傳遞中斷奇怪InterruptedException
調(diào)用interrupt方法,使得上層能感知到中斷奇怪
3取消不成中斷阻塞
存在一些不成中斷的阻塞,譬如:
java.io和java.nio中同步讀寫(xiě)IO
Selector的異步IO
獲取鎖
對(duì)于這些線程的取消,那么需要特定處境特定對(duì)待,譬如對(duì)于socket阻塞,假設(shè)要安好取消,那么需要調(diào)用socket.close
4JVM的關(guān)閉
假設(shè)有任務(wù)需要在JVM關(guān)閉之前做一些清理工作,而不是被JVM強(qiáng)硬關(guān)閉掉,可以使用JVM的鉤子技術(shù),其實(shí)JVM鉤子也只是個(gè)很普遍的技術(shù),也就是用個(gè)map把一些需要JVM關(guān)閉前啟動(dòng)的任務(wù)保存下來(lái),在JVM關(guān)閉過(guò)程中的某個(gè)環(huán)節(jié)來(lái)并發(fā)
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 清廉課題申報(bào)書(shū)怎么寫(xiě)
- 科研課題申報(bào)書(shū)抄襲
- 別墅擴(kuò)建土建合同范本
- 衛(wèi)浴勞動(dòng)合同范本
- 音樂(lè) 課題申報(bào)書(shū)
- 國(guó)家立項(xiàng)課題申報(bào)書(shū)
- 合同附合同范本
- 單項(xiàng)委托預(yù)定酒店合同范本
- 養(yǎng)殖土雞合同范本
- 中環(huán)租房合同范本
- 感染性腹瀉及其防控措施
- 豐田車(chē)系卡羅拉(雙擎)轎車(chē)用戶使用手冊(cè)【含書(shū)簽】
- 商品價(jià)格表(全)
- 管理系統(tǒng)中計(jì)算機(jī)應(yīng)用詳細(xì)課件
- 《多維度兒童智力診斷量表》MIDSC的編制
- 慢阻肺從急性加重期到穩(wěn)定期的全程管理
- 2023年上海市普陀區(qū)高考?xì)v史二模試卷及答案解析
- 瑞達(dá)峰環(huán)境友好型高附加值關(guān)鍵醫(yī)藥中間體、特色原料藥及 GMP 成品藥(仿制藥與創(chuàng)新藥)規(guī)?;a(chǎn)項(xiàng)目(一期)環(huán)評(píng)報(bào)告書(shū)
- 嚴(yán)重創(chuàng)傷的急救處理
- GB/T 1228-2006鋼結(jié)構(gòu)用高強(qiáng)度大六角頭螺栓
- 國(guó)際商法 吳建斌課件 思考題答案
評(píng)論
0/150
提交評(píng)論