Java多線程下載01: 多線程的好處以及斷點續傳原理

1、爲何要使用多線程,多線程真的能提升效率嗎?html

1.1爲何要使用多線程java

多線程編程的目的,就是"最大限度地利用CPU資源",當某一線程的處理不須要佔用CPU而只和I/O等資源打交道時,讓須要佔用CPU資源的其它線程有機會得到CPU資源。從根本上說,這就是多線程編程的最終目的。程序員

由於單線程只會映射到一個CPU上,而多線程會映射到多個CPU上,多線程技術本質是多線程硬件化,因此也會加快程序的執行速度。如今的PC或者手機有不少都是多核的,若是隻使用單一的線程去處理任務,資源得不到充分利用。面試

1.2多線程能提升效率嗎編程

打個比方,好比修一個橋洞,有2種開工方法服務器

方案1、只在橋的一頭挖,直至挖到橋的另外一頭,從而打通橋洞,這能夠當作是單線程。方案2、在橋的兩頭挖,同時開工,最後在橋的中間接通,從而打通橋動,這感受確定比方案一快了不少,比如多線程。網絡

假設每挖5分鐘,就須要清理一下挖出來的泥土。有一個小車在清理它們,工人只有一個。多線程

單線程的作法是:挖5分鐘。而後工人中止挖,小車清理石土的5分鐘裏,工人在等待。2個線程的作發是:挖5分鐘,小車來清理泥土。這5分鐘裏,工人在另外一頭挖。框架

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

1.3線程越多越好?

並非線程越多性能越好,當線程超過必定數量的時候,線程的調度將會變成很大的開銷,反而會讓性能下降,因此要適當使用多線程,不能濫用。兩者不是線性關係。

計算機中通常來講只有一個CPU,也就是說只有一個工人。如今把修橋方案變更一下。方案一:只在山的一頭挖,直至挖到山的另外一頭,從而打通隧道,這能夠當作是單線程。

方案二:在山的兩頭挖,同時開工,最後在山的中間接通,從而打通隧道,這感受確定比1快了不少,比如多線程。

方案二雖然是在山的兩頭開挖,可是因爲工做的人只有一個,因此只有讓這我的在山的兩頭跑,挖一會這頭再去挖另外一頭,來回跑是要花費額外時間的(比如線程的切換和調度)。

再看下面的例子:例子一:A單核單處理器,開一個線程跑循環輸出10萬條打印信息B開100個線程輸出10萬條打印信息。後者比前者慢,由於輸出端是臨界資源(臨界資源:多道程序系統中存在許多進程,它們共享各類資源,然而有不少資源一次只能供一個進程使用。一次僅容許一個進程使用的資源稱爲臨界資源。許多物理設備都屬於臨界資源,如輸入機、打印機、磁帶機等。),線程搶佔的時間大,單線程則無需搶佔。

例子二:A網絡服務器處理,每一個請求開一個線程,請求的處理時間極短,迅速返回。B一次提交10萬個請求,則有10萬次線程建立和銷燬對應於一個工做線程處理這10萬條。請求後者比前者確定快。

2、爲何要使用斷點續傳

在進行數據上傳的時候多是多線程操做,不少圖像數據同時作上傳或者單一的圖像,若是圖像比較多或者單一圖像數據比較大,天然不但願失敗一次或者暫停一次以後徹底重傳,有斷點續傳功能能夠節省網絡流量和節省用戶時間,體驗天然比你一次次的重傳好不少。

3、Java斷點續傳原理

3.1什麼是斷點續傳

所謂斷點續傳,也就是要從文件已經下載的地方開始繼續下載。在之前版本的 HTTP 協議是不支持斷點的,HTTP/1.1 開始就支持了。通常斷點下載時纔用到 Range 和 Content-Range 實體頭。下面會介紹HTTP版本的發展歷程。

3.2什麼是Range?

當用戶在聽一首歌的時候,若是聽到一半(網絡下載了一半),網絡斷掉了,用戶須要繼續聽的時候,文件服務器不支持斷點的話,則用戶須要從新下載這個文件。而Range支持的話,客戶端應該記錄了以前已經讀取的文件範圍,網絡恢復以後,則向服務器發送讀取剩餘Range的請求,服務端只須要發送客戶端請求的那部份內容,而不用整個文件發送回客戶端,以此節省網絡帶寬。

3.3HTTP1.1規範的Range是怎樣一個約定?

若是Server支持Range,首先就要告訴客戶端,咱支持Range,以後客戶端纔可能發起帶Range的請求。這裏套用唐僧的一句話,你不說我怎麼知道呢。response.setHeader('Accept-Ranges', 'bytes');

Server經過請求頭中的Range: bytes=0-xxx來判斷是不是作Range請求,若是這個值存在並且有效,則只發回請求的那部分文件內容,響應的狀態碼變成206,表示Partial Content,並設置Content-Range。若是無效,則返回416狀態碼,代表Request Range Not Satisfiable。若是不包含Range的請求頭,則繼續經過常規的方式響應。

3.4應用場景

假設你要開發一個多線程下載工具,你會天然的想到把文件分割成多個部分,好比4個部分,而後建立4個線程,每一個線程負責下載一個部分,若是文件大小爲403個byte,那麼你的分割方式能夠爲:0-99 (前100個字節),100-199(第二個100字節),200-299(第三個100字節),300-402(最後103個字節)。

分割完成,每一個線程都明白本身的任務,好比線程3的任務是負責下載200-299這部分文件,如今的問題是:線程3發送一個什麼樣的請求報文,纔可以保證只請求文件的200-299字節,而不會干擾其餘線程的任務。這時,咱們可使用HTTP1.1的Range頭。

Range頭域能夠請求實體的一個或者多個子範圍,Range的值爲0表示第一個字節,也就是Range計算字節數是從0開始的:

表示頭500個字節:Range:bytes=0-499

表示第二個500字節:Range:bytes=500-999

表示最後500個字節:Range:bytes=-500

表示500字節之後的範圍:Range:bytes=500-

第一個和最後一個字節:Range:bytes=0-0,-1

同時指定幾個範圍:Range:bytes=500-600,601-999

因此,線程3發送的請求報文必須有這一行:

Range: bytes=200-299

服務器接收到線程3的請求報文,發現這是一個帶有Range頭的GET請求,若是一切正常,服務器的響應報文會有下面這行:HTTP/1.1 206 OK

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

3.5Http協議的發展歷程

HTTP協議到如今爲止總共經歷了3個版本的演化,第一個HTTP協議誕生於1989年3月。

xml屬性描述

HTTP/0.91991年

HTTP/1.01992-1996年

HTTP/1.11997-1999 年

HTTP/2.02012-2014 年

也就是HTTP/1.1 從1997-1999 年就應用了,因此如今基本上是支持斷點續傳的。

3.6模擬Http請求插件推薦

最後推薦一個模擬http請求的插件:HttpRequester,能夠模擬Get/Post請求等,還能夠添加Headers,Parameters參數,很是方便。

在上面 3.2什麼是Range? 已經顯示了使用該插件進行Get請求的截圖。傳送門:HttpRequester怎麼安裝和使用jingyan.baidu.com/article/7c6…

想要朝這方面發展或者真心有興趣的。能夠找我要一些java的學習視頻,Q號碼:3300863615,這個是免費的,但願同窗找我要的時候不要有理所應當的態度,畢竟都是個人心血,但願你是真的有一顆想要學好java的心,我也會盡所能的去幫助你成爲一名優秀的程序員。

加我Q有如下幾個要求:

一、面對目前流行的技術不知從何下手,須要突破技術瓶頸的。

二、在公司待久了,過得很安逸,但跳槽時面試碰壁。須要在短期內進修、跳槽拿高薪的。

三、若是沒有工做經驗,在校大學生,基礎不行紮實,對java工做機制,經常使用設計思想,經常使用java開發框架掌握熟練的。

四、以爲本身很牛B,通常需求都能搞定。可是所學的知識點沒有系統化,很難在技術領域繼續突破的。

  1. 羣號:java互撩學習交流羣 備註好信息!

6.阿里Java高級大牛直播講解知識點,分享知識,多年工做經驗的梳理和總結,帶着你們全面學習

相關文章
相關標籤/搜索