




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、 PAGE25 / NUMPAGES25HYPERLINK :/zhzhl202/article/details/7521377基于Java多線程的下載器源碼剖析(一)分類:HYPERLINK :/zhzhl202/article/category/1136415JavaHYPERLINK :/zhzhl202/article/category/1136415多線程2012-04-28 21:29747人閱讀HYPERLINK :/zhzhl202/article/details/7521377評論(6)HYPERLINK javascript:void(0);收藏HYPERLINK :/zh
2、zhl202/article/details/7521377舉報(bào)HYPERLINK :/tag/details.html?tag=%e5%a4%9a%e7%ba%bf%e7%a8%8b多線程HYPERLINK :/tag/details.html?tag=javajavaHYPERLINK :/tag/details.html?tag=downloaddownloadHYPERLINK :/tag/details.html?tag=bytebyteHYPERLINK :/tag/details.html?tag=filefileHYPERLINK :/tag/details.html?tag=
3、exceptionexception目錄(?)HYPERLINK :/zhzhl202/article/details/7521377+本文實(shí)現(xiàn)了一個(gè)基于Java多線程的下載器,可提供的功能有:1. 對文件使用多線程下載,并顯示每時(shí)刻的下載速度。2. 對多個(gè)下載進(jìn)行管理,包括線程調(diào)度,存管理等。這篇文章的結(jié)構(gòu)如下:首先討論如何實(shí)現(xiàn)利用Java多線程對單個(gè)文件進(jìn)行下載。然后討論當(dāng)系統(tǒng)中有多個(gè)文件下載,如何對這些下載進(jìn)行管理。包括線程調(diào)度,存管理等。一:單個(gè)文件下載的管理1. 單文件下載類層次首先簡要介紹一下單個(gè)文件下載管理的類層次:來一圖來表示。為需要下載的文件創(chuàng)建一個(gè)Download類,Dow
4、nload負(fù)責(zé)管理該文件下載時(shí)的線程管理、文件管理、當(dāng)前速度計(jì)算等操作。根據(jù)線程的數(shù)目tNum,將該文件分為tNum段,每段為一個(gè)DownloadBlock。在實(shí)際下載的過程中,并不是一次把所有的東西下載完,而是每次下載固定size的一段Di。所以每個(gè)DownloadBlock又會分成n段。為每個(gè)DownloadBlock申請一個(gè)線程DownloadThread。其主要作用就是每次下載一段Di,并將其寫入到文件中。2. 單文件下載對于單個(gè)下載,步驟如下連接資源服務(wù)器,獲取資源信息,創(chuàng)建文件切分資源,為每個(gè)線程分配固定的下載區(qū)域。1)封裝下載的屬性在建立下載之前,我們把每一次下載進(jìn)行抽象封裝。首
5、先把URL、目標(biāo)文件等封裝在一個(gè)DownloadConfig類中。其中包含了4個(gè)屬性:javaHYPERLINK :/zhzhl202/article/details/7521377view plainHYPERLINK :/zhzhl202/article/details/7521377copyprivateURLurl;/文件下載地址privateFilefile;/下載文件保存目標(biāo)文件privateintnthread;/下載該文件需要的線程數(shù)privateintpriority;/該下載的優(yōu)先級如下如所示:2)連接資源服務(wù)器,獲取資源信息,創(chuàng)建文件,并指定文件大小javaHYPERLI
6、NK :/zhzhl202/article/details/7521377view plainHYPERLINK :/zhzhl202/article/details/7521377copylength=config.getUrl().openConnection().getContentLength();RandomAccessFilefile=newRandomAccessFile(config.getFile(),rw);file.setLength(length);file.close();3)切分資源,為每個(gè)線程分配固定的下載區(qū)域,并將當(dāng)前的下載加入到隊(duì)列中javaHYPERLINK
7、 :/zhzhl202/article/details/7521377view plainHYPERLINK :/zhzhl202/article/details/7521377copyintsize=length/config.getNthread();for(inti=0;iconfig.getNthread();i+)intstart=i*size;intlen;if(i=config.getNthread()-1)len=length-start;elselen=size;/并將當(dāng)前的下載加入到下載隊(duì)列中addDownloadBlock(getDownloadBlock(start,l
8、en);3)啟動(dòng)線程進(jìn)行下載下載的步驟如下:1. 創(chuàng)建緩存,創(chuàng)建連接。設(shè)置獲取資源數(shù)據(jù)的圍,創(chuàng)建文件,并設(shè)置寫入位置javaHYPERLINK :/zhzhl202/article/details/7521377view plainHYPERLINK :/zhzhl202/article/details/7521377copy/創(chuàng)建緩存byteb;if(block.getLength()Constants.BYTES_READ)b=newbyte(int)block.getLength();elseb=newbyteConstants.BYTES_READ;/創(chuàng)建連接。設(shè)置獲取資源數(shù)據(jù)的圍,從
9、startPos到endPosURLConnectioncon=null;con.setRequestProperty(Range,bytes=+block.getStart()+-+block.getStart()+block.getLength()-1);RandomAccessFilefile=newRandomAccessFile(block.getDownload().getConfig().getFile(),rw);/創(chuàng)建RandomAccessFilefile.seek(block.getStart();/從startPos開始寫入 2. 如果當(dāng)前block的length大于0
10、,則從URL資源處獲取固定大小的資源,并將其寫入到文件中。 3 .更新block塊的start,以與length,如果length大于0,繼續(xù)進(jìn)行2,否則則表示當(dāng)前block已經(jīng)下載完畢,退出該線程。javaHYPERLINK :/zhzhl202/article/details/7521377view plainHYPERLINK :/zhzhl202/article/details/7521377copyInputStreamin=block.getDownload().getConfig().getUrl().openStream();intn;/對該block的文件進(jìn)行下載,while
11、(countblock.getLength()if(needSplit()/檢查該Block是否還需要分塊(即當(dāng)前block剩余的大小大于一次下載的量)longnewLength=(block.getLength()-count)/2;longnewStart=block.getStart()+block.getLength()-newLength;DownloadBlocknewBlock=block.getDownload().getDownloadBlock(newStart,newLength);block.setLength(block.getLength()-newLength);
12、block.getDownload().addDownloadBlock(newBlock);/寫入文件n=in.read(b);if(nblock.getLength()file.write(b,0,(int)(block.getLength()-count);count=block.getLength();elsecount+=n;file.write(b,0,n);/setblockcountindownloadif(n0)/統(tǒng)計(jì)每個(gè)block中已經(jīng)下載的段的個(gè)數(shù),用于計(jì)算當(dāng)前下載的速度。block.getDownload().setBlockCount(block.getStart()
13、,count);in.close();file.close();二 . 當(dāng)前文件下載速度與進(jìn)度計(jì)算如第一個(gè)圖所表示的,每個(gè)Block中又分為了很多的段D1、D2、Dn,因此當(dāng)為了計(jì)算當(dāng)前下載的速度,需要將下載的段D的數(shù)量統(tǒng)計(jì)出來,這里使用了一個(gè)ConcurrentHashMap來保存每個(gè)block已經(jīng)下載完成的段D的數(shù)目。其中key為每個(gè)block的start值,而value為該block已經(jīng)下載完的段D。在當(dāng)前時(shí)刻,我們需要統(tǒng)計(jì)當(dāng)前Download已經(jīng)下載完成段D的數(shù)量,然后再和上一時(shí)刻的相比較,則可以得出當(dāng)前的下載速度。具體代碼見下:javaHYPERLINK :/zhzhl202/art
14、icle/details/7521377view plainHYPERLINK :/zhzhl202/article/details/7521377copyclassCheckSpeedTaskextendsTimerTaskprivatestaticfinalLoglog=LogFactory.getLog(CheckSpeedTask.class);privateDownloaddownload;privateConcurrentHashMapblockCounts;privatelongspeed=0;/Byte/Sprivatelongcount=0;/Totaldownloadedb
15、ytecountprivatelonglastCount=0;privatelongtime=0;/ChecktimeprivatelonglastTime=0;publicCheckSpeedTask(Downloaddownload,longstartTime,ConcurrentHashMapblockCounts)this.download=download;this.lastTime=startTime;this.blockCounts=blockCounts;Overridepublicvoidrun()trytime=System.currentTimeMillis();coun
16、t=0;/需要統(tǒng)計(jì)當(dāng)前已經(jīng)下載完成段D的數(shù)量。for(longc:blockCounts.values()count+=c;speed=(count-lastCount)/(time-lastTime)/1000);log.debug(blockCounts.size()+threadsaredownloading+download+,cuttentis+speed+Byte/S,+(count*1.0)/download.getLength()*100+%downloaded);download.setCount(count);download.setSpeed(speed);lastTim
17、e=time;lastCount=count;catch(Exceptione)/TODO:handleexceptione.printStackTrace();這樣我們就可以在Thread類的run()函數(shù)中,計(jì)算當(dāng)前下載的速度javaHYPERLINK :/zhzhl202/article/details/7521377view plainHYPERLINK :/zhzhl202/article/details/7521377copywhile(activeThreads.size()0|blockQueue.size()0)Thread.sleep(1000);checkSpeed();
18、上面的代碼演示了如何使用Java多線程對單個(gè)文件進(jìn)行下載,接下來我們繼續(xù)討論如何對多個(gè)下載進(jìn)行調(diào)度、管理等HYPERLINK :/zhzhl202/article/details/7521940基于Java多線程的下載器源碼剖析(二)分類:HYPERLINK :/zhzhl202/article/category/1136415JavaHYPERLINK :/zhzhl202/article/category/1136415多線程2012-04-29 10:36571人閱讀HYPERLINK :/zhzhl202/article/details/7521940評論(6)HYPERLINK ja
19、vascript:void(0);收藏HYPERLINK :/zhzhl202/article/details/7521940舉報(bào)HYPERLINK :/tag/details.html?tag=%e5%a4%9a%e7%ba%bf%e7%a8%8b多線程HYPERLINK :/tag/details.html?tag=javajavaHYPERLINK :/tag/details.html?tag=downloaddownloadHYPERLINK :/tag/details.html?tag=integerintegerHYPERLINK :/tag/details.html?tag=th
20、readthreadHYPERLINK :/tag/details.html?tag=timertimer目錄(?)HYPERLINK :/zhzhl202/article/details/7521940+三:多個(gè)文件下載的管理這一節(jié)我們主要來講一下如何對多個(gè)文件的下載進(jìn)行管理首先來看一下整個(gè)系統(tǒng)的UML圖從最下面開始說起:Download代表一個(gè)下載類,對每一個(gè)文件都需要?jiǎng)?chuàng)建一個(gè)Download實(shí)例,用于對該文件下載線程的管理。其中每個(gè)Download中都有以下幾個(gè)對象:javaHYPERLINK :/zhzhl202/article/details/7521940view plainHYP
21、ERLINK :/zhzhl202/article/details/7521940copyprivateConcurrentLinkedQueueblockQueue;privateConcurrentLinkedQueueblockCache;privateConcurrentHashMapblockCounts;privateConcurrentLinkedQueueactiveThreads;其中blockQueue是一個(gè)隊(duì)列,用于存儲當(dāng)前需要下載的DownloadBlock。Download對文件進(jìn)行切分形成的DownloadBlock會被放入到放入到blockQueue中,供以后的下
22、載。blockCache為block存緩存池,主要是為了能夠復(fù)用已經(jīng)建立好的DownloadBlock。blockCounts為一個(gè)Map,其中key為每個(gè)block的start值,而value為該block已經(jīng)下載完的段D。主要作用是統(tǒng)計(jì)出當(dāng)前已經(jīng)每個(gè)Block已經(jīng)下載完的段D,以計(jì)算實(shí)時(shí)下載速度activeThreads 主要是為了存儲該Thread中所有的活躍線程。DownloadBlock是一個(gè)下載塊,其里面有3個(gè)成員變量javaHYPERLINK :/zhzhl202/article/details/7521940view plainHYPERLINK :/zhzhl202/arti
23、cle/details/7521940copyprivateDownloaddownload;/其所屬的Downloadprivatelongstart;/下載文件起始處privatelonglength;/下載文件的長度DownloadThread是指下載進(jìn)程,每個(gè)DownloadBlock都需要啟動(dòng)一個(gè)DownloadThread去進(jìn)行下載。即javaHYPERLINK :/zhzhl202/article/details/7521940view plainHYPERLINK :/zhzhl202/article/details/7521940copynewDownloadThread(b
24、lock).start()DownloadDeamon為了一個(gè)守護(hù)線程。其部主要為了下載所有的需要下載DownloadBlockjavaHYPERLINK :/zhzhl202/article/details/7521940view plainHYPERLINK :/zhzhl202/article/details/7521940copyprivateDownloadListdownloads;/當(dāng)前系統(tǒng)中所有的下載列表privateExecutorServicethreadPool;/線程池Downloader 代表整個(gè)下載系統(tǒng),整個(gè)系統(tǒng)中只有一個(gè)實(shí)例對象,因此我們需要保證系統(tǒng)中只有一個(gè)實(shí)例
25、對象。javaHYPERLINK :/zhzhl202/article/details/7521940view plainHYPERLINK :/zhzhl202/article/details/7521940copyprivateDownloaderConfigconfig;/Downloader配置privateDownloadListdownloads;/當(dāng)前系統(tǒng)所有的下載列表privateThreaddeamon;/守護(hù)進(jìn)程privateConcurrentLinkedQueueblockCache;/當(dāng)前系統(tǒng)的緩存privateTimertimer;/看了上面一大堆的東西,我保證你現(xiàn)
26、在很暈,OK,我們從使用的角度來看整個(gè)系統(tǒng)是如何運(yùn)行的。下面是示例代碼。javaHYPERLINK :/zhzhl202/article/details/7521940view plainHYPERLINK :/zhzhl202/article/details/7521940copypublicstaticvoidmain(Stringargs)Downloaderdownloader=Downloader.getInstance();/下載第一個(gè)文件Stringurl1= s:/tmsvm.googlecode./files/tmsvm_src_v1.1.0.rar;StringsaveFi
27、le1=data/tmsvm_src_v1.1.0.rar;DownloadConfigconfig=newDownloadConfig();tryconfig.setUrl(newURL(url1);config.setFile(newFile(saveFile1);config.setNthread(newInteger(5);config.setPriority(newInteger(6);/將第一個(gè)下載加入到下載列表中downloader.addDownload(newDownload(config,downloader.getTimer();catch(MalformedURLExc
28、eptione)/TODOAuto-generatedcatchblocke.printStackTrace();/下載第二個(gè)文件Stringurl2= s:/tmsvm.googlecode./files/Tmsvm%E5%8F%82%E8%80%83%E6%96%87%E6%A1%A3%28v1.1.0%29.rar;StringsaveFile2=data/Tmsvm參考文檔(v1.1.0).rar;tryconfig.setUrl(newURL(url2);config.setFile(newFile(saveFile2);config.setNthread(newInteger(5)
29、;config.setPriority(newInteger(6);/將第二個(gè)下載加入到下載列表中downloader.addDownload(newDownload(config,downloader.getTimer();catch(MalformedURLExceptione)/TODOAuto-generatedcatchblocke.printStackTrace();1. 系統(tǒng)初始化首先來看這一行行:javaHYPERLINK :/zhzhl202/article/details/7521940view plainHYPERLINK :/zhzhl202/article/detai
30、ls/7521940copyDownloaderdownloader=Downloader.getInstance();Downloader是這個(gè)下載器的總調(diào)度師,一山不容二虎,當(dāng)然在系統(tǒng)運(yùn)行過程中,只能有一個(gè)Downloader的實(shí)例,因此我們需要用單例模式來保證這一點(diǎn)。首先要取得downloader實(shí)例,即系統(tǒng)的初始化。我們看系統(tǒng)初始化需要做什么?javaHYPERLINK :/zhzhl202/article/details/7521940view plainHYPERLINK :/zhzhl202/article/details/7521940copypublicstaticDownl
31、oadergetInstance()if(downloader=null)downloader=newDownloader(newDownloaderConfig();returndownloader;privateDownloader(DownloaderConfigconfig)super();this.config=config;start();上面的代碼中的start()函數(shù)中到底做了什么呢?初始化blockCache緩存,其中blockCache為ConcurrentLinkedQueue類型。啟動(dòng)守護(hù)進(jìn)程DownloadDeamon具體代碼如下:javaHYPERLINK :/zh
32、zhl202/article/details/7521940view plainHYPERLINK :/zhzhl202/article/details/7521940copyprivatevoidstart()blockCache=newConcurrentLinkedQueue();/初始化緩存downloads=newDownloadList();deamon=newThread(newDownloadDeamon(downloads);/初始化守護(hù)進(jìn)程deamon.setDaemon(true);deamon.start();timer=newTimer(Constants.TIMER
33、_NAME,true);上面代碼中啟動(dòng)了一個(gè)守護(hù)進(jìn)程。那么這個(gè)守護(hù)進(jìn)程在啟動(dòng)的時(shí)候在做什么事情呢?我們來看一下他的run()函數(shù)javaHYPERLINK :/zhzhl202/article/details/7521940view plainHYPERLINK :/zhzhl202/article/details/7521940copypublicvoidrun()System.out.println(Createthreadpool);threadPool=Executors.newCachedThreadPool();/初始化線程池DownloadBlockblock;while(tru
34、e)block=getDownloadBlock();/不斷從當(dāng)前系統(tǒng)中獲取待下載的DownloadBlockif(block!=null)(Createnewdownloadthreadfor+block);/啟動(dòng)線程執(zhí)行下載threadPool.execute(newDownloadThread(block);/將當(dāng)前Block從其所在的Download中移除block.getDownload().removeDownloadBlock(block);tryThread.sleep(1000);catch(InterruptedExceptione)/TODOAuto-generatedc
35、atchblockSystem.out.println(Downloaddeamonstopedbyuser);break;守護(hù)進(jìn)程所做的事情就是不斷獲取將要進(jìn)行下載的Block,然后啟動(dòng)線程去進(jìn)行下載。來看一下獲取Block的策略:這里不斷的從當(dāng)前下載列表中獲取所有的Download,然后從里面選取最需要下載的文件,“最需要下載”定義為剩余的待下載量最多。其具體的代碼看下方:javaHYPERLINK :/zhzhl202/article/details/7521940view plainHYPERLINK :/zhzhl202/article/details/7521940copypriv
36、ateDownloadBlockgetDownloadBlock()downs=downloads.toArray();if(downs=null|downs.length=0)returnnull;Downloaddownload=downs0;for(Downloaddown:downs)/找最需要下載的Download進(jìn)行下載if(down.getRemainThread()download.getRemainThread()download=down;download.descRemainThread();returndownload.getDownloadBlock();2. 新建下
37、載上面講解的是系統(tǒng)初始化所做的事情。那么當(dāng)我們把開始下載一個(gè)文件時(shí)系統(tǒng)是怎么運(yùn)行的呢?javaHYPERLINK :/zhzhl202/article/details/7521940view plainHYPERLINK :/zhzhl202/article/details/7521940copy/下載第一個(gè)文件Stringurl1= s:/tmsvm.googlecode./files/tmsvm_src_v1.1.0.rar;StringsaveFile1=data/tmsvm_src_v1.1.0.rar;DownloadConfigconfig=newDownloadConfig();
38、tryconfig.setUrl(newURL(url1);config.setFile(newFile(saveFile1);config.setNthread(newInteger(5);config.setPriority(newInteger(6);/將第一個(gè)下載加入到下載列表中downloader.addDownload(newDownload(config,downloader.getTimer();catch(MalformedURLExceptione)/TODOAuto-generatedcatchblocke.printStackTrace();我們重點(diǎn)來看這一句:java
39、HYPERLINK :/zhzhl202/article/details/7521940view plainHYPERLINK :/zhzhl202/article/details/7521940copy/將第一個(gè)下載加入到下載列表中downloader.addDownload(newDownload(config,downloader.getTimer();addDownload的定義如下javaHYPERLINK :/zhzhl202/article/details/7521940view plainHYPERLINK :/zhzhl202/article/details/7521940c
40、opypublicbooleanaddDownload(Downloaddownload)newThread(download).start();returndownloads.add(download);這段代碼做了兩件事情:為Download啟動(dòng)一下線程。Download線程所做的事情就是把當(dāng)前的文件根據(jù)線程數(shù)目進(jìn)行切分。把當(dāng)前Download加入到DownloadList中。OK,我們看看,Download是切分文件時(shí)是如何與整個(gè)系統(tǒng)聯(lián)系在一起。javaHYPERLINK :/zhzhl202/article/details/7521940view plainHYPERLINK :/zh
41、zhl202/article/details/7521940copypublicvoidrun()trybegin=System.currentTimeMillis();/getlength(Begindownload+config.getUrl();length=config.getUrl().openConnection().getContentLength();(Totalsize:+length);/createfile(Createfile+config.getFile();RandomAccessFilefile=newRandomAccessFile(config.getFile
42、(),rw);file.setLength(length);(Createdwithlength=+length);file.close();intsize=length/config.getNthread();/addinitialblockslog.debug(Addinitial+config.getNthread()+downloadblocks);for(inti=0;i0|blockQueue.size()0)Thread.sleep(1000);checkSpeed();/stopthetaskscheckSpeedTask.cancel();splitBlockTask.can
43、cel();longtotal=System.currentTimeMillis()-begin;speed=length/(total/1000);(Completedownload+config.getUrl()+n+Totaltime:+total+ms+n+Averagespeed:+speed+Byte/s);log.debug(this+putallblockinblockCachebacktodownloadersystem);for(DownloadBlockblock:blockCache)Downloader.getInstance().putDownloadBlock(b
44、lock);catch(FileNotFoundExceptione)/TODOAuto-generatedcatchblocke.printStackTrace();catch(IOExceptione)/TODOAuto-generatedcatchblocke.printStackTrace();catch(InterruptedExceptione)/TODOAuto-generatedcatchblocke.printStackTrace();上面的代碼,我們在第一篇中已經(jīng)講解過了,這里我們會重點(diǎn)看javaHYPERLINK :/zhzhl202/article/details/75
45、21940view plainHYPERLINK :/zhzhl202/article/details/7521940copyaddDownloadBlock(getDownloadBlock(start,len);其意思是將當(dāng)前的切分出來的Block放入到待下載隊(duì)列中去。而我們在守護(hù)進(jìn)程那里,看到他不斷的會從當(dāng)前系統(tǒng)中找最需要下載的Download,然后再從Download中取出下載隊(duì)列的Block進(jìn)行下載javaHYPERLINK :/zhzhl202/article/details/7521940view plainHYPERLINK :/zhzhl202/article/details
46、/7521940copy/DownloadDemen不斷的獲取DownloadBlockwhile(true)block=getDownloadBlock();if(block!=null)System.out.println(Createnewdownloadthreadfor+block);threadPool.execute(newDownloadThread(block);block.getDownload().removeDownloadBlock(block);javaHYPERLINK :/zhzhl202/article/details/7521940view plainHYP
47、ERLINK :/zhzhl202/article/details/7521940copy/getDownloadBlock()定義如下:privateDownloadBlockgetDownloadBlock()downs=downloads.toArray();if(downs=null|downs.length=0)returnnull;Downloaddownload=downs0;for(Downloaddown:downs)if(down.getRemainThread()download.getRemainThread()download=down;download.descRe
48、mainThread();returndownload.getDownloadBlock();javaHYPERLINK :/zhzhl202/article/details/7521940view plainHYPERLINK :/zhzhl202/article/details/7521940copy/而download.getDownloadBlock()定義如下所示:publicDownloadBlockgetDownloadBlock()returnblockQueue.peek();寫到這里,整個(gè)的系統(tǒng)框架目錄就非常清晰了:Downloader, DownloadDemen, Do
49、wnload 之間是通過DownloadBlock聯(lián)系起來的。當(dāng)有一個(gè)文件需要下載時(shí),Downloader 把該Download加入到DownloadList中。而Download自身會通過切分文件創(chuàng)建出多個(gè)DownloadBlock。DownloadDemen每時(shí)每刻都在獲取DownloadBlock,賦予其線程進(jìn)行下載。下一節(jié),我們會重點(diǎn)講解一下Downloader如何系統(tǒng)中的緩存進(jìn)行處理的。HYPERLINK :/zhzhl202/article/details/7522074基于Java多線程的下載器源碼剖析(三)分類:HYPERLINK :/zhzhl202/article/cate
50、gory/1136415JavaHYPERLINK :/zhzhl202/article/category/1136415多線程2012-04-29 11:29657人閱讀HYPERLINK :/zhzhl202/article/details/7522074評論(12)HYPERLINK javascript:void(0);收藏HYPERLINK :/zhzhl202/article/details/7522074舉報(bào)HYPERLINK :/tag/details.html?tag=%e5%a4%9a%e7%ba%bf%e7%a8%8b多線程HYPERLINK :/tag/details.
51、html?tag=javajavaHYPERLINK :/tag/details.html?tag=downloaddownloadHYPERLINK :/tag/details.html?tag=%e4%bb%bb%e5%8a%a1任務(wù)HYPERLINK :/tag/details.html?tag=concurrencyconcurrencyHYPERLINK :/tag/details.html?tag=%e7%bd%91%e7%bb%9c網(wǎng)絡(luò)目錄HYPERLINK :/zhzhl202/article/details/7522074(?)HYPERLINK :/zhzhl202/art
52、icle/details/7522074+四:緩存管理在Thread切分文件時(shí),會創(chuàng)建非常多的DownloadBlock,為了減少創(chuàng)建、銷毀Block所帶來對效率上的影響,我們會把已經(jīng)創(chuàng)建好的DownloadBlock放入到緩存中,當(dāng)Download需要DownloadBlock時(shí)直接從緩存中取得。即我們使用緩存來對已經(jīng)申請的存重復(fù)利用。在每個(gè)Download類中都有一個(gè)緩存池,即ConcurrentLinkedQueue blockCache;而整個(gè)的系統(tǒng)Downloader也會有一個(gè)大的ConcurrentLinkedQueue blockCache;那么這兩者是怎樣的關(guān)系呢?在Downl
53、oad類對文件進(jìn)行切分的時(shí)候,需要?jiǎng)?chuàng)建DownloadBlock,而DownloadBlock是根據(jù)getDownloadBlock函數(shù)來獲取到的。javaHYPERLINK :/zhzhl202/article/details/7522074view plainHYPERLINK :/zhzhl202/article/details/7522074copy/*從blockcache獲取一塊DownloadBlock。*cache中的block都是已經(jīng)下載完畢的。*paramstartblock塊的下載開始位置*paramlengthblock塊需要下載的長度*return返回一個(gè)創(chuàng)建好的bl
54、ock塊。*/publicDownloadBlockgetDownloadBlock(longstart,longlength)DownloadBlockblock;/先從當(dāng)前的Download中看是否有if(blockCache.size()0)block=blockCache.poll();elseblock=Downloader.getInstance().getDownloadBlock();block.setDownload(this);block.setStart(start);block.setLength(length);returnblock;上面的代碼中,首先會從當(dāng)前Dow
55、nload所擁有的Cache中獲取DownloadBlock,如果有空閑的DownloadBlock,則直接取出。如果沒有則需要從當(dāng)前系統(tǒng)中去申請。當(dāng)當(dāng)前的DownloadBlock使用DownloadThread下載完畢之后,他所擁有的這個(gè)DownloadBlock會交給其所在的Download,以供剩余新建的DownloadBlock使用。javaHYPERLINK :/zhzhl202/article/details/7522074view plainHYPERLINK :/zhzhl202/article/details/7522074copyblock.getDownload().putDownloadBlock(block);而當(dāng)整個(gè)文件都下載完畢之后,需要把當(dāng)前Download的所有緩存歸還給系統(tǒng)(Downloader)javaHYPERLINK :/zhzhl202/article/details/7522074view plainHYPERLINK :/zhzhl202/article/de
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 體育館預(yù)制塊運(yùn)輸合同
- 海島酒店賓客接送合同
- 2025年協(xié)效助劑項(xiàng)目投資可行性研究分析報(bào)告
- 第4課《海燕》教學(xué)設(shè)計(jì) 2024-2025學(xué)年統(tǒng)編版語文九年級下冊
- 2025年度專業(yè)醫(yī)院清潔消毒服務(wù)合同(含傳染病防控)
- 二零二五年度糧油市場調(diào)研合同范文電子版
- 2025年度銀行房屋按揭貸款與房屋租賃信用擔(dān)保服務(wù)協(xié)議
- 第1課 從食物采集到食物生產(chǎn) 教學(xué)設(shè)計(jì)-2023-2024學(xué)年高中歷史統(tǒng)編版(2019)選擇性必修2
- 2025年果肉果汁飲料項(xiàng)目節(jié)能評估報(bào)告(節(jié)能專)
- 2025年NITI基記憶合金材料項(xiàng)目合作計(jì)劃書
- 效率提升和品質(zhì)改善方案
- 中山大學(xué)抬頭信紙中山大學(xué)橫式便箋紙推薦信模板a
- 無形資產(chǎn)評估完整版課件
- 義務(wù)教育學(xué)科作業(yè)設(shè)計(jì)與管理指南
- 《汽車發(fā)展史》PPT課件(PPT 75頁)
- 常暗之廂(7規(guī)則-簡體修正)
- 反詐騙防詐騙主題教育宣傳圖文PPT教學(xué)課件
- 制冷系統(tǒng)方案的設(shè)計(jì)pptx課件
- 修心七要原文
- 納期管理流程圖
- 中國TBHQ行業(yè)市場調(diào)研報(bào)告
評論
0/150
提交評論