官术网_书友最值得收藏!

1.6 多線程編程的優(yōu)勢和風險

多線程編程具有以下優(yōu)勢。

? 提高系統(tǒng)的吞吐率(Throughput)。多線程編程使得一個進程中可以有多個并發(fā)(Concurrent,即同時進行的)的操作。例如,當一個線程因為I/O操作而處于等待狀態(tài)時,其他線程仍然可以執(zhí)行其操作。

? 提高響應性(Responsiveness)。在使用多線程編程的情況下,對于GUI軟件(如桌面應用程序)而言,一個操作慢(比如從服務器上下載一個大文件)并不會導致軟件界面出現(xiàn)被“凍住”的現(xiàn)象而無法響應用戶的其他操作;對于Web應用程序而言,一個請求的處理速度慢并不會影響對其他請求的處理[11]

? 充分利用多核(Multicore)CPU資源。如今多核CPU的設(shè)備越來越普及,就算是手機這樣的消費類設(shè)備也普遍使用多核CPU。實施恰當?shù)亩嗑€程編程有助于我們充分利用設(shè)備的多核CPU資源,從而避免了資源浪費。

? 盡量少地使用系統(tǒng)資源。一個進程中的多個線程可以共享其所在進程申請的資源(如內(nèi)存空間),因此使用多個線程相比于使用多個進程進行編程來說,節(jié)約了系統(tǒng)資源。

? 簡化程序的結(jié)構(gòu)。線程可以簡化復雜應用程序的結(jié)構(gòu)。

多線程編程也有自身的問題與風險,包括:

? 線程安全(Thread Safe)問題。當多個線程共享數(shù)據(jù)的時候,如果沒有采取相應的并發(fā)訪問控制措施,那么就可能產(chǎn)生數(shù)據(jù)一致性問題,如讀取臟數(shù)據(jù)(過期的數(shù)據(jù))、丟失更新(某些線程所做的更新被其他線程所做的更新覆蓋)等。使用鎖(包括synchronized關(guān)鍵字和ReentrantLock等)能夠保證線程安全是大家所熟知的,本書后續(xù)章節(jié)則會提供一些不借助鎖來實現(xiàn)線程安全的方案。

? 線程的生命特征(Thread Liveness)問題。一個線程從創(chuàng)建到運行結(jié)束的整個生命周期會經(jīng)歷若干個狀態(tài)。從單個線程的角度來看,RUNNABLE狀態(tài)是我們所期望的狀態(tài)。但實際上,代碼編寫不適當可能導致某些線程一直處于等待其他線程釋放鎖的狀態(tài)(BLOCKED狀態(tài)),即產(chǎn)生了死鎖(Dead Lock)。例如,線程T1擁有鎖L1,并試圖獲取鎖L2,而此時線程T2擁有鎖L2并試圖獲取鎖L1,這就導致線程T1和T2一直處于等待對方釋放鎖且又得不到鎖的狀態(tài)。當然,一直忙碌的線程也可能會出現(xiàn)問題,它可能面臨活鎖(Live Lock)問題,即一個線程一直在嘗試某個操作但就是沒有進展,這就好比室內(nèi)窗戶上的蒼蠅向著陽光飛卻一直沒能飛出去一樣。另外,線程是一種稀缺的計算資源,一個系統(tǒng)所擁有的CPU數(shù)量相比于該系統(tǒng)中存在的線程數(shù)量而言總是少之又少的。某些情況下可能出現(xiàn)線程饑餓(Starvation)的問題,即某些線程永遠無法獲取被CPU執(zhí)行的機會而永遠處于RUNNABLE狀態(tài)的READY子狀態(tài)。

? 上下文切換。由于CPU資源的稀缺性,上下文切換可以看作多線程編程的必然副產(chǎn)物,它增加了系統(tǒng)的消耗,不利于提高系統(tǒng)的吞吐率。

? 可靠性。多線程編程一方面有利于可靠性,例如,某個線程意外提前停止了,但這并不影響其他線程繼續(xù)執(zhí)行各自的處理操作。另一方面,線程是進程的一個組件,它總是存在于特定的進程中,如果這個進程由于某種原因意外提前停止了,比如,某個Java進程由于內(nèi)存泄漏導致Java虛擬機崩潰而意外停止了,那么該進程中所有的線程也就隨之無法繼續(xù)運行。因此,從提高軟件可靠性的角度來看,在某些情況下可能要考慮多進程、多線程的編程方式[12],而非簡單的單進程多線程的編程方式。

主站蜘蛛池模板: 南召县| 富源县| 安图县| 克山县| 梅河口市| 合水县| 海南省| 罗甸县| 星座| 长岭县| 宁陕县| 大田县| 庆元县| 榆中县| 循化| 天祝| 察哈| 曲沃县| 山丹县| 陇川县| 峡江县| 昌黎县| 荆州市| 密山市| 运城市| 贵定县| 阿拉善左旗| 庆元县| 东乌珠穆沁旗| 南靖县| 泽库县| 老河口市| 扎赉特旗| 西和县| 曲松县| 康乐县| 满洲里市| 茂名市| 连城县| 新闻| 昌邑市|