刚学了下多线程的下载,可能是初次接触的原因吧,理解起来觉得稍微有点难,所以想写一篇博客来记录下,加深自己理解的同时,也希望能够帮到一些刚接触的小伙伴。由于涉及到网络的传输,那么就会涉及到http协议。建议在读本文之前您对http协议有一定的了解。
线程可以通俗的理解为下载的通道,一个线程就是文件下载的一个通道,多线程就是同时打开了多个通道对文件进行下载。当服务器提供下载服务时,用户之间共享带宽,在优先级相同的情况下,总服务器会对总下载线程进行平均分配,我们平时用的迅雷下载就是多线程下载。
引用> <编辑>多线程的下载大致可以分为如下几个步骤:编辑>1:获取目标文件的大小(totalSize)
按照常识,我们在下载一个文件之前,通常情况下是要知道该文件的大小,这样才好在本地留好足量的空间来存储,免得出现还未下载完,存储空间就爆了的情况。为了方便代码的演示,本文在本地tomcat服务器的webapps/根目录下新建一个用法的文件,里面存储了0123456789这10字节的数据。
引用>2:确定要开启几个线程(threadCount)
需要的文件在服务器上,那我们要开通几个通道去下载呢?一般情况下这是由CPU去决定的,但是CPU开启线程的数目也是有限的,不是想开几个线程就开几个线程。所开线程的最大数量=(CPU核数+ 1),例如你的CPU核数为4,那么电脑最多可以开启5条线程。为了方便代码演示,本文的threadCount=3
引用>3:计算平均每个线程需要下载多少个字节的数据(blockSize)
理想情况下多线程下载是按照平均分配原则的,即:单线程下载的字节数等于文件总大小除以开启的线程总条数,当不能整除时,则最后开启的线程将剩余的字节一起下载,例如:本文中的totalSize=10, threadCount=3,则前两个开启的线程下载3 KB的数据,第三个开启的线程需要下载(3 + 1)KB的数据。
引用>4:计算各个线程要下载的字节范围。
平时我们做项目讲究分工明确,同理多线程下载也需要明确各个下载的字节范围,这样才能将文件高效、快速,准确的下载下来。即在下载过程中,各个线程都要明确自己的开始索引(startIndex)和结束索引(endIndex)。
引用>
7:使用RandomAccessFile随机文件访问类。创建一个RandomAccessFile对象,将返回的字节流写到文件指定的范围
此处有个注意事项:让RandomAccessFile对象写字节流之前,需要移动RandomAccessFile对象到指定的位置开始写。
引用><代码> raf.seek (startIndex); 代码>以上就是多线程下载的大致步骤。代码如下:
<代码> com . example,包 进口java.io.InputStream; 进口java.io.RandomAccessFile; 进口java.net.HttpURLConnection; 进口java.net.URL; 公开课DownloadTest { 私有静态最终字符串路径=" http://localhost: 8080/用法”; 公共静态void main (String [] args){抛出异常/* * * 1 .获取目标文件的大小 */int totalSize=新的URL(路径).openConnection () .getContentLength (); System.out.println(“目标文件的总大小为:" + totalSize +“B”);/* * * 2。确定开启几个线程 *开启线程的总CPU数=核数+ 1,例如:CPU核数为4,则最多可开启5条线程 */.availableProcessors int availableProcessors=Runtime.getRuntime () (); System.out.println (“CPU核数是:“+ availableProcessors); int threadCount=3;/* * * 3。计算每个线程要下载多少个字节 */int blockSize=totalSize/threadCount;//每次循环启动一条线程下载 for (int threadId=0;threadId多线程下载的基本原理和用法