Java简单多线程断点下载

简介:

使用多线程下载文件可以更快完成文件的下载,多线程下载文件之所以快,是因为其抢占的服务器资源多。如:假设服务器同时最多服务100个用户,在服务器中一条线程对应一个用户,100条线程在计算机中并非并发执行,而是由CPU划分时间片轮流执行,如果A应用使用了99条线程下载文件,那么相当于占用了99个用户的资源,假设一秒内CPU分配给每条线程的平均执行时间是10ms,A应用在服务器中一秒内就得到了990ms的执行时间,而其他应用在一秒内只有10ms的执行时间。就如同一个水龙头,每秒出水量相等的情况下,放990毫秒的水肯定比放10毫秒的水要多。

 

 
  1. XML/HTML 代码复制内容到剪贴板  
  2.       
  3. package cn.mzba.download;        
  4.         
  5. import java.io.File;        
  6. import java.io.InputStream;        
  7. import java.io.RandomAccessFile;        
  8. import java.net.HttpURLConnection;        
  9. import java.net.URL;        
  10.         
  11. public class MulThreadDownloader {        
  12.         
  13.     /**        
  14.      * 1、首先获取网络上的内容,然后获取文件的长度,标题。 然后在本地上生成一个同样大小并且同名的文件。 2、执行线程        
  15.      * 3、线程首先定义一个随机输入流,用来下载文件同步写入本地文件 设置Range从指定的开始位置-结束位置下载文件。        
  16.      * 4、获取服务器返回的输入流写入文件。        
  17.      *         
  18.      */        
  19.     public static void main(String[] args) throws Exception {        
  20.         String path = "http://www.wo...56c.jpg";        
  21.         new MulThreadDownloader().download(path, 3);        
  22.         System.in.read();        
  23.     }        
  24.         
  25.     public void download(String path, int threadsize) throws Exception {        
  26.         URL url = new URL(path);        
  27.         HttpURLConnection conn = (HttpURLConnection) url.openConnection();        
  28.         conn.setRequestMethod("GET");        
  29.         conn.setConnectTimeout(5 * 1000);        
  30.         int length = conn.getContentLength(); // 获取文件长度        
  31.         File localfile = new File(getFileName(path));        
  32.         RandomAccessFile file = new RandomAccessFile(localfile, "rwd");        
  33.         file.setLength(length);        
  34.         file.close();        
  35.         // 计算每条线程下载的数据长度        
  36.         int block = length % threadsize == 0 ? length / threadsize : length        
  37.                 / threadsize + 1;        
  38.         for (int i = 0; i < threadsize; i++) {        
  39.             new DownLoadThread(i, url, block, localfile).start();        
  40.         }        
  41.     }        
  42.         
  43.     private final class DownLoadThread extends Thread {        
  44.         
  45.         private int threadid;        
  46.         private URL url;        
  47.         private int block;        
  48.         private File localfile;        
  49.         
  50.         public DownLoadThread(int threadid, URL url, int block, File localfile) {        
  51.             this.threadid = threadid;        
  52.             this.block = block;        
  53.             this.url = url;        
  54.             this.localfile = localfile;        
  55.         }        
  56.         
  57.         @Override        
  58.         public void run() {        
  59.             int startposition = threadid * block; // 从网络文件的什么位置开始下载数据        
  60.             int endposition = startposition + block - 1; // 下载到文件的什么位置结束        
  61.             RandomAccessFile file;        
  62.             try {        
  63.                 file = new RandomAccessFile(localfile, "rwd");        
  64.                 file.seek(startposition);        
  65.                 HttpURLConnection conn = (HttpURLConnection) url        
  66.                         .openConnection();        
  67.                 conn.setRequestMethod("GET");        
  68.                 conn.setConnectTimeout(5 * 1000);        
  69.                 conn.setRequestProperty("Range", "bytes=" + startposition + "-"        
  70.                         + endposition);        
  71.                 InputStream is = conn.getInputStream();        
  72.                 byte[] buffer = new byte[1024];        
  73.                 int len = 0;        
  74.                 while ((len = is.read(buffer)) != -1) {        
  75.                     file.write(buffer, 0, len);        
  76.                 }        
  77.                 is.close();        
  78.                 file.close();        
  79.                 System.out.println("线程id" + threadid + "已经下载完成");        
  80.             } catch (Exception e) {        
  81.                 // TODO Auto-generated catch block        
  82.                 e.printStackTrace();        
  83.             }        
  84.         
  85.             super.run();        
  86.         }        
  87.         
  88.     }        
  89.         
  90.     public static String getFileName(String path) {        
  91.         return path.substring(path.lastIndexOf("/") + 1);        
  92.     }        
  93. }    

 


     本文转自06peng 51CTO博客,原文链接:http://blog.51cto.com/06peng/962470,如需转载请自行联系原作者




相关文章
|
7月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
395 1
|
7月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
365 1
|
8月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
Java 数据库 Spring
350 0
|
8月前
|
算法 Java
Java多线程编程:实现线程间数据共享机制
以上就是Java中几种主要处理多线程序列化资源以及协调各自独立运行但需相互配合以完成任务threads 的技术手段与策略。正确应用上述技术将大大增强你程序稳定性与效率同时也降低bug出现率因此深刻理解每项技术背后理论至关重要.
537 16
|
9月前
|
缓存 并行计算 安全
关于Java多线程详解
本文深入讲解Java多线程编程,涵盖基础概念、线程创建与管理、同步机制、并发工具类、线程池、线程安全集合、实战案例及常见问题解决方案,助你掌握高性能并发编程技巧,应对多线程开发中的挑战。
|
9月前
|
数据采集 存储 前端开发
Java爬虫性能优化:多线程抓取JSP动态数据实践
Java爬虫性能优化:多线程抓取JSP动态数据实践
|
10月前
|
Java API 调度
从阻塞到畅通:Java虚拟线程开启并发新纪元
从阻塞到畅通:Java虚拟线程开启并发新纪元
492 83
|
10月前
|
安全 算法 Java
Java 多线程:线程安全与同步控制的深度解析
本文介绍了 Java 多线程开发的关键技术,涵盖线程的创建与启动、线程安全问题及其解决方案,包括 synchronized 关键字、原子类和线程间通信机制。通过示例代码讲解了多线程编程中的常见问题与优化方法,帮助开发者提升程序性能与稳定性。
423 0
|
10月前
|
存储 Java 调度
Java虚拟线程:轻量级并发的革命性突破
Java虚拟线程:轻量级并发的革命性突破
517 83

热门文章

最新文章