? ? ? ? 本系列譯自jakob jenkov的Java并發(fā)多線程教程袱蜡,個(gè)人覺得很有收獲材诽。由于個(gè)人水平有限渤昌,不對(duì)之處還望矯正!
? ? ?盡管多線程有諸多的挑戰(zhàn)澈驼,但是多線程被廣泛使用的原因有以下幾點(diǎn):
1辛燥、對(duì)資源的充分利用。
2缝其、簡(jiǎn)化程序設(shè)計(jì)
3挎塌、響應(yīng)的及時(shí)性
資源的充分利用
? ? ? ?假設(shè)一個(gè)應(yīng)用程序從本地文件系統(tǒng)中讀取并處理一個(gè)文件,讓我們來假設(shè)從硬盤讀取文件需要5秒氏淑,處理文件需要兩秒勃蜘,那么處理兩個(gè)文件則需要:
5秒 讀取A文件
2秒 處理A文件
5秒 讀取B文件
2秒 處理B文件
共需14秒
當(dāng)從硬盤讀取文件的時(shí)候,CPU大部分時(shí)間用在等待從硬盤讀取數(shù)據(jù)假残,CPU 在等待的這段時(shí)間是非崇怨保空閑的,是可以被利用來做其他事情的辉懒,通過改變執(zhí)行順序阳惹,CPU 可以被更好的利用】袅看下面的執(zhí)行順序:
5秒 ?讀取A文件
5秒 讀取B文件+2秒處理A文件
2秒 處理B文件
共需12秒
到CPU等待A文件讀取的時(shí)候莹汤,開始讀取B文件,當(dāng)B文件正在讀取的時(shí)候颠印,CPU 開始處理A文件纲岭,記住,當(dāng)CPU 等待從硬盤讀取文件的時(shí)候线罕,CPU 幾乎是空閑的止潮。
通常,CPU 在等待IO操作時(shí)钞楼,可以做其他的事情的喇闸,不光是磁盤IO,網(wǎng)絡(luò)IO也是一樣的
簡(jiǎn)化程序設(shè)計(jì)
如果你打算用一個(gè)單線程的程序去處理上面的問題,你不得不時(shí)刻跟蹤每個(gè)文件的讀取和處理狀態(tài)询件。而用多線程燃乍,你只需要啟動(dòng)兩個(gè)線程,而每個(gè)線程只需負(fù)責(zé)單個(gè)文件讀取和處理宛琅。這些線程會(huì)被blocked當(dāng)?shù)却龔拇疟P上讀取文件刻蟹,在等待的同時(shí),另外的線程可以利用CPU 來處理它已經(jīng)讀到的數(shù)據(jù)嘿辟,這樣做的結(jié)果就是座咆,磁盤一直處于繁忙的狀態(tài)痢艺,不斷地從磁盤讀取數(shù)據(jù)到內(nèi)存中。這樣做介陶,對(duì)于磁盤和CPU 的利用率得到提升堤舒,同時(shí)對(duì)于程序來說也更簡(jiǎn)單,因?yàn)槊總€(gè)線程只需去跟蹤一個(gè)文件的讀取和處理狀態(tài)
響應(yīng)的及時(shí)性
將單線程轉(zhuǎn)變?yōu)槎嗑€程的另一個(gè)目的是更具有響應(yīng)的及時(shí)性哺呜。假設(shè)一個(gè)服務(wù)端程程序在一個(gè)端口上監(jiān)聽請(qǐng)求舌缤,當(dāng)收到請(qǐng)求后,它對(duì)這個(gè)請(qǐng)求進(jìn)行相應(yīng)的處理某残,然后再返回去監(jiān)聽另外的請(qǐng)求国撵。服務(wù)端程序如下:
while(server is active){
? ?listen for the request
? ?process request
}
如果這個(gè)請(qǐng)求花費(fèi)了很長(zhǎng)的時(shí)間去處理,那么客戶端就不能在此期間發(fā)送任何請(qǐng)求到服務(wù)端玻墅,只有當(dāng)服務(wù)端處理完當(dāng)前請(qǐng)求再次回到監(jiān)聽時(shí)才能接受新的請(qǐng)求介牙。另一種設(shè)計(jì)是監(jiān)聽線程把接受到的請(qǐng)求交給工作線程(work ?thread )然后立即返回監(jiān)聽。工作線程會(huì)對(duì)請(qǐng)求進(jìn)行處理澳厢,并對(duì)客戶端返回一個(gè)結(jié)果环础。這種設(shè)計(jì)模式如下:
while(server is active){
listen for request
handle request to work thread
}
這種方式,監(jiān)聽線程會(huì)很快繼續(xù)進(jìn)行監(jiān)聽剩拢,因此更多的客戶端可以發(fā)送更多的請(qǐng)求到服務(wù)端线得,服務(wù)端也變的更具響應(yīng)性。這對(duì)桌面應(yīng)用程序也是一樣的徐伐。