Java多線程下載框架01:多線程的好處以及斷點續(xù)傳原理

一、為什么要使用多線程脉漏,多線程真的能提高效率嗎?

  • 1.1為什么要使用多線程

多線程編程的目的切距,就是"最大限度地利用CPU資源",當某一線程的處理不需要占用CPU而只和I/O等資源打交道時惨远,讓需要占用CPU資源的其它線程有機會獲得CPU資源谜悟。從根本上說,這就是多線程編程的最終目的北秽。

因為單線程只會映射到一個CPU上葡幸,而多線程會映射到多個CPU上,多線程技術(shù)本質(zhì)是多線程硬件化贺氓,所以也會加快程序的執(zhí)行速度∥颠叮現(xiàn)在的PC或者手機有很多都是多核的,如果只使用單一的線程去處理任務,資源得不到充分利用辙培。

  • 1.2多線程能提高效率嗎

打個比方,比如修一個橋洞蔑水,有2種開工方法

方案一、只在橋的一頭挖扬蕊,直至挖到橋的另一頭搀别,從而打通橋洞,這可以看成是單線程尾抑。
方案二歇父、在橋的兩頭挖,同時開工再愈,最后在橋的中間接通榜苫,從而打通橋動,這感覺肯定比方案一快了很多翎冲,好比多線程单刁。

假設(shè)每挖5分鐘,就需要清理一下挖出來的泥土府适。有一個小車在清理它們,工人只有一個肺樟。

單線程的做法是: 挖5分鐘檐春。然后工人停止挖,小車清理石土的5分鐘里么伯,工人在等待疟暖。
2個線程的做發(fā)是: 挖5分鐘,小車來清理泥土。這5分鐘里俐巴,工人在另一頭挖骨望。

這個比喻至少能說明點問題:小車清理泥土,就相當于磁盤io等相對于cpu計算來說比較慢的操作欣舵。在cpu空閑的時候可以讓其去做其它事情擎鸠,達到充分利用的效果。

  • 1.3線程越多越好缘圈?
image.png

并不是線程越多性能越好劣光,當線程超過一定數(shù)量的時候,線程的調(diào)度將會變成很大的開銷糟把,反而會讓性能降低绢涡,所以要適當使用多線程,不能濫用遣疯。二者不是線性關(guān)系雄可。

計算機中一般來說只有一個CPU,也就是說只有一個工人〔現(xiàn)在把修橋方案變動一下数苫。
方案一:只在山的一頭挖,直至挖到山的另一頭夭坪,從而打通隧道戈二,這可以看成是單線程立莉。

方案二:在山的兩頭挖,同時開工,最后在山的中間接通诽里,從而打通隧道,這感覺肯定比1快了很多丑勤,好比多線程稳强。

方案二雖然是在山的兩頭開挖,但是由于工作的人只有一個间涵,所以只有讓這個人在山的兩頭跑仁热,挖一會這頭再去挖另一頭,來回跑是要花費額外時間的(好比線程的切換和調(diào)度)勾哩。

再舉二個例子:
例子一:
A單核單處理器,開一個線程跑循環(huán)輸出10萬條打印信息
B開100個線程輸出10萬條打印信息抗蠢。
后者比前者慢,因為輸出端是臨界資源(臨界資源:多道程序系統(tǒng)中存在許多進程,它們共享各種資源思劳,然而有很多資源一次只能供一個進程使用迅矛。一次僅允許一個進程使用的資源稱為臨界資源。許多物理設(shè)備都屬于臨界資源潜叛,如輸入機秽褒、打印機壶硅、磁帶機等。),線程搶占的時間大,單線程則無需搶占销斟。

例子二:
A網(wǎng)絡(luò)服務器處理,每個請求開一個線程,請求的處理時間極短,迅速返回庐椒。
B一次提交10萬個請求,則有10萬次線程創(chuàng)建和銷毀對應于一個工作線程處理這10萬條。請求后者比前者肯定快蚂踊。

二约谈、為什么要使用斷點續(xù)傳

在進行數(shù)據(jù)上傳的時候可能是多線程操作,很多圖像數(shù)據(jù)同時做上傳或者單一的圖像悴势,如果圖像比較多或者單一圖像數(shù)據(jù)比較大窗宇,自然不希望失敗一次或者暫停一次之后完全重傳,有斷點續(xù)傳功能可以節(jié)省網(wǎng)絡(luò)流量和節(jié)省用戶時間特纤,體驗自然比你一次次的重傳好很多军俊。

三、Java斷點續(xù)傳原理

3.1什么是斷點續(xù)傳

所謂斷點續(xù)傳捧存,也就是要從文件已經(jīng)下載的地方開始繼續(xù)下載粪躬。在以前版本的 HTTP 協(xié)議是不支持斷點的,HTTP/1.1 開始就支持了昔穴。一般斷點下載時才用到 Range 和 Content-Range 實體頭镰官。下面會介紹HTTP版本的發(fā)展歷程。

3.2什么是Range吗货?

模擬http請求

當用戶在聽一首歌的時候泳唠,如果聽到一半(網(wǎng)絡(luò)下載了一半),網(wǎng)絡(luò)斷掉了宙搬,用戶需要繼續(xù)聽的時候笨腥,文件服務器不支持斷點的話,則用戶需要重新下載這個文件勇垛。而Range支持的話脖母,客戶端應該記錄了之前已經(jīng)讀取的文件范圍,網(wǎng)絡(luò)恢復之后闲孤,則向服務器發(fā)送讀取剩余Range的請求谆级,服務端只需要發(fā)送客戶端請求的那部分內(nèi)容,而不用整個文件發(fā)送回客戶端讼积,以此節(jié)省網(wǎng)絡(luò)帶寬肥照。

3.3HTTP1.1規(guī)范的Range是怎樣一個約定?

如果Server支持Range勤众,首先就要告訴客戶端建峭,咱支持Range,之后客戶端才可能發(fā)起帶Range的請求决摧。這里套用唐僧的一句話,你不說我怎么知道呢。response.setHeader('Accept-Ranges', 'bytes');

Server通過請求頭中的Range: bytes=0-xxx來判斷是否是做Range請求掌桩,如果這個值存在而且有效边锁,則只發(fā)回請求的那部分文件內(nèi)容,響應的狀態(tài)碼變成206波岛,表示Partial Content茅坛,并設(shè)置Content-Range。如果無效则拷,則返回416狀態(tài)碼贡蓖,表明Request Range Not Satisfiable。如果不包含Range的請求頭煌茬,則繼續(xù)通過常規(guī)的方式響應斥铺。

3.4應用場景

假設(shè)你要開發(fā)一個多線程下載工具,你會自然的想到把文件分割成多個部分坛善,比如4個部分晾蜘,然后創(chuàng)建4個線程,每個線程負責下載一個部分眠屎,如果文件大小為403個byte剔交,那么你的分割方式可以為:0-99 (前100個字節(jié)),100-199(第二個100字節(jié))改衩,200-299(第三個100字節(jié))岖常,300-402(最后103個字節(jié))。

分割完成葫督,每個線程都明白自己的任務竭鞍,比如線程3的任務是負責下載200-299這部分文件,現(xiàn)在的問題是:線程3發(fā)送一個什么樣的請求報文候衍,才能夠保證只請求文件的200-299字節(jié)笼蛛,而不會干擾其他線程的任務。這時蛉鹿,我們可以使用HTTP1.1的Range頭滨砍。

Range頭域可以請求實體的一個或者多個子范圍,Range的值為0表示第一個字節(jié)妖异,也就是Range計算字節(jié)數(shù)是從0開始的:

表示頭500個字節(jié):Range: bytes=0-499
表示第二個500字節(jié):Range: bytes=500-999 
表示最后500個字節(jié):Range: bytes=-500 
表示500字節(jié)以后的范圍:Range: bytes=500- 
第一個和最后一個字節(jié):Range: bytes=0-0,-1
同時指定幾個范圍:Range: bytes=500-600,601-999  

所以惋戏,線程3發(fā)送的請求報文必須有這一行:

Range: bytes=200-299

服務器接收到線程3的請求報文,發(fā)現(xiàn)這是一個帶有Range頭的GET請求他膳,如果一切正常响逢,服務器的響應報文會有下面這行:
HTTP/1.1 206 OK

表示處理請求成功,響應報文還有這一行
Content-Range: bytes 200-299/403
斜杠后面的403表示文件的大小

3.5Http協(xié)議的發(fā)展歷程

HTTP協(xié)議到現(xiàn)在為止總共經(jīng)歷了3個版本的演化棕孙,第一個HTTP協(xié)議誕生于1989年3月舔亭。

xml屬性 描述
HTTP/0.9 1991年
HTTP/1.0 1992-1996年
HTTP/1.1 1997-1999年
HTTP/2.0 2012-2014年

也就是HTTP/1.1 從1997-1999 年就應用了些膨,所以現(xiàn)在基本上是支持斷點續(xù)傳的。

3.6模擬Http請求插件推薦

最后推薦一個模擬http請求的插件:HttpRequester,可以模擬Get/Post請求等,還可以添加Headers,Parameters參數(shù),非常方便钦铺。

模擬POST請求

在上面“3.2什么是Range订雾?”已經(jīng)顯示了使用該插件進行Get請求的截圖。
傳送門:HttpRequester怎么安裝和使用
https://jingyan.baidu.com/article/7c6fb4280b6a4180642c900c.html矛洞。

本文公號地址,后續(xù)文章持續(xù)更新中,微信掃描下方二維碼免費關(guān)注!洼哎,點此查看全部最新文章


我的博客
我的簡書
我的GitHub,喜歡的話給個star吧

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市沼本,隨后出現(xiàn)的幾起案子噩峦,更是在濱河造成了極大的恐慌,老刑警劉巖抽兆,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件识补,死亡現(xiàn)場離奇詭異,居然都是意外死亡郊丛,警方通過查閱死者的電腦和手機李请,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來厉熟,“玉大人导盅,你說我怎么就攤上這事∽嵘” “怎么了白翻?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長绢片。 經(jīng)常有香客問我滤馍,道長,這世上最難降的妖魔是什么底循? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任巢株,我火速辦了婚禮,結(jié)果婚禮上熙涤,老公的妹妹穿的比我還像新娘阁苞。我一直安慰自己,他們只是感情好祠挫,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布那槽。 她就那樣靜靜地躺著,像睡著了一般等舔。 火紅的嫁衣襯著肌膚如雪骚灸。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天慌植,我揣著相機與錄音甚牲,去河邊找鬼义郑。 笑死,一個胖子當著我的面吹牛鳖藕,可吹牛的內(nèi)容都是我干的魔慷。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼著恩,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蜻展?” 一聲冷哼從身側(cè)響起喉誊,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎纵顾,沒想到半個月后伍茄,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡施逾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年敷矫,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片汉额。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡曹仗,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蠕搜,到底是詐尸還是另有隱情怎茫,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布妓灌,位于F島的核電站轨蛤,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏虫埂。R本人自食惡果不足惜祥山,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望掉伏。 院中可真熱鬧缝呕,春花似錦、人聲如沸岖免。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽颅湘。三九已至话侧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間闯参,已是汗流浹背瞻鹏。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工悲立, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人新博。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓薪夕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親赫悄。 傳聞我的和親對象是個殘疾皇子原献,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容