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,如需转载请自行联系原作者




相关文章
|
8天前
|
监控 安全 Java
在 Java 中使用线程池监控以及动态调整线程池时需要注意什么?
【10月更文挑战第22天】在进行线程池的监控和动态调整时,要综合考虑多方面的因素,谨慎操作,以确保线程池能够高效、稳定地运行,满足业务的需求。
79 38
|
5天前
|
安全 Java
java 中 i++ 到底是否线程安全?
本文通过实例探讨了 `i++` 在多线程环境下的线程安全性问题。首先,使用 100 个线程分别执行 10000 次 `i++` 操作,发现最终结果小于预期的 1000000,证明 `i++` 是线程不安全的。接着,介绍了两种解决方法:使用 `synchronized` 关键字加锁和使用 `AtomicInteger` 类。其中,`AtomicInteger` 通过 `CAS` 操作实现了高效的线程安全。最后,通过分析字节码和源码,解释了 `i++` 为何线程不安全以及 `AtomicInteger` 如何保证线程安全。
java 中 i++ 到底是否线程安全?
|
7天前
|
安全 Java
在 Java 中使用实现 Runnable 接口的方式创建线程
【10月更文挑战第22天】通过以上内容的介绍,相信你已经对在 Java 中如何使用实现 Runnable 接口的方式创建线程有了更深入的了解。在实际应用中,需要根据具体的需求和场景,合理选择线程创建方式,并注意线程安全、同步、通信等相关问题,以确保程序的正确性和稳定性。
|
1天前
|
安全 Java 调度
Java中的多线程编程入门
【10月更文挑战第29天】在Java的世界中,多线程就像是一场精心编排的交响乐。每个线程都是乐团中的一个乐手,他们各自演奏着自己的部分,却又和谐地共同完成整场演出。本文将带你走进Java多线程的世界,让你从零基础到能够编写基本的多线程程序。
8 1
|
5天前
|
缓存 Java 调度
Java中的多线程编程:从基础到实践
【10月更文挑战第24天】 本文旨在为读者提供一个关于Java多线程编程的全面指南。我们将从多线程的基本概念开始,逐步深入到Java中实现多线程的方法,包括继承Thread类、实现Runnable接口以及使用Executor框架。此外,我们还将探讨多线程编程中的常见问题和最佳实践,帮助读者在实际项目中更好地应用多线程技术。
12 3
|
7天前
|
监控 安全 Java
Java多线程编程的艺术与实践
【10月更文挑战第22天】 在现代软件开发中,多线程编程是一项不可或缺的技能。本文将深入探讨Java多线程编程的核心概念、常见问题以及最佳实践,帮助开发者掌握这一强大的工具。我们将从基础概念入手,逐步深入到高级主题,包括线程的创建与管理、同步机制、线程池的使用等。通过实际案例分析,本文旨在提供一种系统化的学习方法,使读者能够在实际项目中灵活运用多线程技术。
|
5天前
|
缓存 安全 Java
Java中的多线程编程:从基础到实践
【10月更文挑战第24天】 本文将深入探讨Java中的多线程编程,包括其基本原理、实现方式以及常见问题。我们将从简单的线程创建开始,逐步深入了解线程的生命周期、同步机制、并发工具类等高级主题。通过实际案例和代码示例,帮助读者掌握多线程编程的核心概念和技术,提高程序的性能和可靠性。
8 2
|
6天前
|
Java
Java中的多线程编程:从基础到实践
本文深入探讨Java多线程编程,首先介绍多线程的基本概念和重要性,接着详细讲解如何在Java中创建和管理线程,最后通过实例演示多线程的实际应用。文章旨在帮助读者理解多线程的核心原理,掌握基本的多线程操作,并能够在实际项目中灵活运用多线程技术。
|
8天前
|
Prometheus 监控 Cloud Native
JAVA线程池监控以及动态调整线程池
【10月更文挑战第22天】在 Java 中,线程池的监控和动态调整是非常重要的,它可以帮助我们更好地管理系统资源,提高应用的性能和稳定性。
36 4
|
8天前
|
Java 数据处理 开发者
Java多线程编程的艺术:从入门到精通####
【10月更文挑战第21天】 本文将深入探讨Java多线程编程的核心概念,通过生动实例和实用技巧,引导读者从基础认知迈向高效并发编程的殿堂。我们将一起揭开线程管理的神秘面纱,掌握同步机制的精髓,并学习如何在实际项目中灵活运用这些知识,以提升应用性能与响应速度。 ####
30 3