多线程下载在我们生活中非常常见,比如迅雷就是我们常用的多线程的下载工具,当然还有断点续传,断点续传我们在下一节来讲,android手机端下载文件时也可以用多线程下载,我们这里是在java中写一个测试,其实android中的实现和java是一样的,学会了java就知道怎么在android中实现了,废话不多说了,怎么实现多线程和多线程的原理是什么样的,现在我们来学习一下。
<!--more-->

多线程下载原理及步骤:

  1. 在本地创建一个大小跟服务器文件相同大小的临时文件。

  2. 计算分配几个线程去下载服务器上的资源,知道每个线程下载文件的位置。

步骤二的具体方法和操作:

文件的长度/3(线程的个数)=每个线程下载文件的大小

假设文件长度为10,则

线程1:0-2

线程2:3-5

线程3:6-文件末尾

每个线程下载的位置的计算方式:

开始位置:

(线程id - 1)* 每一块的大小

结束位置:

(线程id * 每一块大小)-1

  1. 开启多(3)个线程,每一个线程下载对应位置的文件

  2. 如果所有的线程都把自己的数据下载完毕了,服务器上的资源就被下载到本地了。

在这里在介绍一个有关多线程下载的java中的相关类RandomAccessFile

RandomAccessFile 随机文件访问类

只有RandomAccessFile才有seek搜寻方法,而这个方法也只适用于文件。通过seek()方法指定位置,定位文件,即可以指定随机写文件的时候从哪个位置开始写。利用这个类才能实现文件的多线程下载。

基本原理和相关介绍如上,就这些,现在我们看看代码:

package net.loonggg.test;import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;/**** 多线程下载* * @author loonggg* */
public class MutilDownloader {// 开启的线程的个数public static final int THREAD_COUNT = 3;public static void main(String[] args) throws Exception {String path = "http://down.360safe.com/yunpan/360wangpan_setup.exe";// 连接服务器,获取一个文件,获取文件的长度,在本地创建一个大小跟服务器文件大小一样的临时文件URL url = new URL(path);HttpURLConnection conn = (HttpURLConnection) url.openConnection();// 设置网络请求超时时间conn.setConnectTimeout(5000);// 设置请求方式conn.setRequestMethod("GET");int code = conn.getResponseCode();if (code == 200) {// 服务器返回的数据的长度,实际就是文件的长度int length = conn.getContentLength();System.out.println("----文件总长度----" + length);// 在客户端本地创建出来一个大小跟服务器端文件一样大小的临时文件RandomAccessFile raf = new RandomAccessFile("yunpan.exe", "rwd");// 指定创建的这个文件的长度raf.setLength(length);// 关闭rafraf.close();// 假设是3个线程去下载资源// 平均每一个线程下载的文件的大小int blockSize = length / THREAD_COUNT;for (int threadId = 1; threadId <= THREAD_COUNT; threadId++) {// 计算每个线程下载的开始位置和结束位置int startIndex = (threadId - 1) * blockSize;int endIndex = threadId * blockSize - 1;if (threadId == THREAD_COUNT) {endIndex = length;}System.out.println("----threadId---" + threadId+ "--startIndex--" + startIndex + "--endIndex--"+ endIndex);// 开启每一个线程new DownloadThread(path, threadId, startIndex, endIndex).start();}}}/*** 下载文件的子线程,每一个线程下载对应位置的文件* * @author loonggg* */public static class DownloadThread extends Thread {private int threadId;private int startIndex;private int endIndex;private String path;/*** @param path*            下载文件在服务器上的路径* @param threadId*            线程id* @param startIndex*            线程下载的开始位置* @param endIndex*            线程下载的结束位置*/public DownloadThread(String path, int threadId, int startIndex,int endIndex) {this.path = path;this.threadId = threadId;this.startIndex = startIndex;this.endIndex = endIndex;}@Overridepublic void run() {try {URL url = new URL(path);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setRequestMethod("GET");// 重要:请求服务器下载部分的文件 指定文件的位置conn.setRequestProperty("Range", "bytes=" + startIndex + "-"+ endIndex);conn.setConnectTimeout(5000);// 从服务器请求全部资源的状态码200 ok 如果从服务器请求部分资源的状态码206 okint code = conn.getResponseCode();System.out.println("---code---" + code);InputStream is = conn.getInputStream();// 已经设置了请求的位置,返回的是当前位置对应的文件的输入流RandomAccessFile raf = new RandomAccessFile("yunpan.exe", "rwd");// 随机写文件的时候从哪个位置开始写raf.seek(startIndex);// 定位文件int len = 0;byte[] buffer = new byte[1024];while ((len = is.read(buffer)) != -1) {raf.write(buffer, 0, len);}is.close();raf.close();System.out.println("线程" + threadId + ":下载完毕了!");} catch (Exception e) {e.printStackTrace();}}}}

公众号:非著名程序员(smart_android) 欢迎大家关注,每天一篇原创技术文章。

多线程系列之学习多线程下载的基本原理和基本用法(1)相关推荐

  1. java多线程系列八之多线程之间的交互:线程阀

    注意!注意!如果代码出现乱序,请双击代码部分,则会出现排序正常的代码 1.阻塞队列BlockingQueue 先理解Queue,Deque,BlockingQueue的概念. Queue(队列):用于 ...

  2. 撬开多线程的大门——学习多线程必须掌握的基本概念

  3. java死锁业务场景_【深入浅出多线程系列十二】:什么是死锁?(场景+代码示例)...

    在学习Java的道路上,是否路过多线程时总让你很迷惘:很不巧,我也是,而使我们感到很迷惘主要原因都源于没有对概念的深深的理解和实践.所以我决定漫步Java多线程,同你一起会会多线程. 多线程系列 多线 ...

  4. python3爬虫系列16之多线程爬取汽车之家批量下载图片

    python3爬虫系列16之多线程爬取汽车之家批量下载图片 1.前言 上一篇呢,python3爬虫系列14之爬虫增速多线程,线程池,队列的用法(通俗易懂),主要介绍了线程,多线程,和两个线程池的使用. ...

  5. Java多线程系列(一):最全面的Java多线程学习概述

    Java并发编程的技能基本涵括以下5方面: 多线程 线程池 线程锁 并发工具类 并发容器 多线程的4种创建方式 继承Thread 实现Runnable接口 实现Callable接口 以及线程池来创建线 ...

  6. java线程 教程_Java多线程系列教程

    Java多线程系列教程 多线程是Java中不可避免的一个重要主体.从本章开始,我们将展开对多线程的学习.接下来的内容是对Java多线程内容的讲解,涉及到的内容包括,Object类中的wait(), n ...

  7. java 秒杀多线程_秒杀多线程系列 - 随笔分类 - Joyfulmath - 博客园

    随笔分类 - 秒杀多线程系列 秒杀多线程系列,该系列转载至CSDN MoreWindows: http://blog.csdn.net/morewindows/article/details/7392 ...

  8. Java多线程系列(六):深入详解Synchronized同步锁的底层实现

    谈到多线程就不得不谈到Synchronized,很多同学只会使用,缺不是很明白整个Synchronized的底层实现原理,这也是面试经常被问到的环节,比如: synchronized的底层实现原理 s ...

  9. Java多线程系列(十一):ReentrantReadWriteLock的实现原理与锁获取详解

    我们继续Java多线程与并发系列之旅,之前我们分享了Synchronized 和 ReentrantLock 都是独占锁,即在同一时刻只有一个线程获取到锁. 然而在有些业务场景中,我们大多在读取数据, ...

最新文章

  1. 《预训练周刊》第21期:FlipDA:有效且稳健的数据增强小样本学习、开放域低资源适应的生成式聊天机器人...
  2. 互联网公司之外,银联等大型企业是如何玩转软件研发的?
  3. CSS 详细解读定位属性 position 以及参数
  4. 常用的图像增强处理办法
  5. neuralcoref使用教程-指代消解
  6. 使用CMS垃圾收集器产生的问题和解决方案
  7. java用栈处理四则运算_Java 用栈处理四则运算
  8. PowerDesigner 中的name与comment转换(转)
  9. 品优购案例之横向列表伪元素的应用
  10. TP框架使用ajax的post请求方式下载文件
  11. EC2(elastic compute cloud,弹性计算云,又称EC2实例)
  12. 推荐16个高清图片网站,可做网站背景
  13. 二---------
  14. AWS 上的云原生 Jenkins
  15. xilinx 7系列 外部时钟如何接入FPGA
  16. 【CSS Selector】小猪网短租房(Python R)
  17. Unity虚拟现实(VR)无编码游戏开发视频教程
  18. Python量化交易学习笔记(18)——放量突破布林线中轨买入策略
  19. SpringBoot整合WebService(服务端+客户端)
  20. 任务分配问题关于医院接口开发

热门文章

  1. 计算机应用基础期末考试电大,(电大)期末考试2017年广播电视大学网考《计算机应用基础》重点复习题目汇总版(理论题及操作题)...
  2. C++ :常用文件、文件夹操作汇总
  3. 【AI有识境】如何掌握好图像分割算法?值得你看的技术综述
  4. 【pytorch速成】Pytorch图像分类从模型自定义到测试
  5. 在vc2005中使用MoveWindow()调整控件大小,不能及时刷新,在vc6中则可以
  6. 全球农企对话国际农民丰收节贸易会·万祥军:拜耳谋定领先
  7. 农产品区域公用品牌 农民丰收节交易会青岛谋定农业品牌
  8. 如何避免HBase写入过快引起的各种问题
  9. Judge Route Circle
  10. 第三章 python数据规整化