【JAVA应用】多线程断点下载

简介:

问题:多线程下载的好处?

多线程下载比单线程下载快,主要的原因是采用多线程下载,可以抢占更多的服务器资源。抢占Cpu的处理空间,实现更快的下载速度


问题:多线程下载位置的确定?

开启N条线程下载文件,假设文件大小为buf,那么每条线程的下载量为:
buf%N==0?buf/N:buf/N+1;

那么,每一条线程应该从网络文件的什么位置开始下载??

假设线程id号threadid为0,1,2,每一条线程下载的数据量为block=4

第一个文件从threadid*block开始下载,结束位置(threadid+1)*block-1

所以公式为:
int start=threadid*block;
int end=(threadid+1)*block-1;



多线程下载源码(仅供参考)

package cn.deu.hpu.download;

import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

public class MulThreadDownLoad {
	
	public static void main(String[] args) throws Exception{
		String path="http://192.168.111.104:8080/web/gg.jpg";
		new MulThreadDownLoad().download(path,3);
	}
	
	/*下载文件
	 * path 网络文件路径
	 * */
	public void download(String path,int threadsize)throws Exception{
		URL url=new URL(path);
		HttpURLConnection conn=(HttpURLConnection) url.openConnection();
		conn.setConnectTimeout(5000);
		conn.setRequestMethod("GET");
		if(conn.getResponseCode()==200){
			//取得网络文件的长度
			int length=conn.getContentLength();
			File file=new File(getFilename(path));
			//随机访问文件类(生成一个与网络文件长度相等的本地文件)
			RandomAccessFile accessFile=new RandomAccessFile(file, "rwd");
			accessFile.setLength(length);
			accessFile.close();
			
			//计算每条线程需要下载的数据量
			int block=length%threadsize==0?length/threadsize:length/threadsize+1;
			for (int threadid = 0; threadid< threadsize; threadid++) {
				new DownloadThread(threadid,block,url,file).start();
			}
		}else{
			System.out.println("下载失败!");
		}
		
	}

	private String getFilename(String path) {
		//从URL地址的最后一个"/"后开始记录文件名
		return path.substring(path.lastIndexOf("/")+1);
	}
	
	private class DownloadThread extends Thread{
		private int threadid;
		private int block;
		private URL url;
		private File file;
		public DownloadThread(int threadid,int block,URL url,File file){
			this.threadid=threadid;
			this.block=block;
			this.url=url;
			this.file=file;
		}
		
		public void run(){
			//计算该线程从网络文件的什么位置开始下载
			int start=threadid*block;
			//下载到网络文件的什么位置结束
			int end=(threadid+1)*block-1;
			try {
				RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");
				//从某一个位置开始写入数据
				accessFile.seek(start);				
				HttpURLConnection conn=(HttpURLConnection) url.openConnection();
				conn.setConnectTimeout(5000);
				conn.setRequestMethod("GET");
				//指定行网络文件的某个区域下载数据(开始位置-结束位置)
				conn.setRequestProperty("Range", "bytes="+start+"-"+end);
				//请求某一段数据的话,请求码不是200,是206
				if(conn.getResponseCode()==206){
					InputStream instream=conn.getInputStream();
					byte [] buffer=new byte[1024];
					int len=0;
					while((len=instream.read(buffer))!=-1){
						accessFile.write(buffer,0,len);
					}
					accessFile.close();
					instream.close();
				}
				System.out.println("第"+(threadid+1)+"线程已经下载完成");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}

转载请注明出处!程序猿之洞:http://blog.csdn.net/acmman

相关文章
|
23小时前
|
消息中间件 缓存 NoSQL
Java多线程实战-CompletableFuture异步编程优化查询接口响应速度
Java多线程实战-CompletableFuture异步编程优化查询接口响应速度
|
1天前
|
数据采集 存储 Java
高德地图爬虫实践:Java多线程并发处理策略
高德地图爬虫实践:Java多线程并发处理策略
|
1天前
|
安全 Java 大数据
探索Java的奇妙世界:语言特性与实际应用
探索Java的奇妙世界:语言特性与实际应用
|
1天前
|
缓存 Java
【Java基础】简说多线程(上)
【Java基础】简说多线程(上)
5 0
|
2天前
|
并行计算 算法 安全
Java从入门到精通:2.1.3深入学习Java核心技术——掌握Java多线程编程
Java从入门到精通:2.1.3深入学习Java核心技术——掌握Java多线程编程
|
2天前
|
安全 Java 编译器
是时候来唠一唠synchronized关键字了,Java多线程的必问考点!
本文简要介绍了Java中的`synchronized`关键字,它是用于保证多线程环境下的同步,解决原子性、可见性和顺序性问题。从JDK1.6开始,synchronized进行了优化,性能得到提升,现在仍可在项目中使用。synchronized有三种用法:修饰实例方法、静态方法和代码块。文章还讨论了synchronized修饰代码块的锁对象、静态与非静态方法调用的互斥性,以及构造方法不能被同步修饰。此外,通过反汇编展示了`synchronized`在方法和代码块上的底层实现,涉及ObjectMonitor和monitorenter/monitorexit指令。
15 0
|
2天前
|
监控 安全 Java
在Java中如何优雅的停止一个线程?可别再用Thread.stop()了!
在Java中如何优雅的停止一个线程?可别再用Thread.stop()了!
10 2
|
2天前
|
Java 调度
Java面试必考题之线程的生命周期,结合源码,透彻讲解!
Java面试必考题之线程的生命周期,结合源码,透彻讲解!
28 1
|
SQL 存储 Java
Java 应用与数据库的关系| 学习笔记
快速学习 Java 应用与数据库的关系。
170 0
Java 应用与数据库的关系| 学习笔记
|
SQL 存储 Java
Java 应用与数据库的关系| 学习笔记
快速学习 Java 应用与数据库的关系。
165 0
Java 应用与数据库的关系| 学习笔记

热门文章

最新文章