多线程下载

什么是多线程?

                多线程可以理解为下载的通道,一个线程就是一个文件的下载通道,多线程也就是同时开启好几个下载通道。当服务器提供下载服务时,使用下载者是共享带宽的,在优先级相同的情况下,总服务器会对总下载线程进行平均分配。不难理解,如果你线程多的话,那下载的越快。

多线程原理:

           多线程下载的原理是这样的:通常服务器同时与多个用户连接,用户之间共享带宽。如果N个用户的优先级都相同,那么每个用户连接到该服务器上的实际带宽就是服务器带宽的N分之一。可以想象,如果用户数目较多,则每个用户只能占有可怜的一点带宽,下载将会是个漫长的过程。
         如果你通过多个线程同时与服务器连接,那么你就可以榨取到较高的带宽了。例如原来有10个用户都通过单一线程与服务器相连,服务器的总带宽假设为56Kbps,则每个用户(每个线程)分到的带宽是5.6Kbps,即0.7K字节/秒。如果你同时打开两个线程与服务器连接,那么共有11个线程与服务器连接,而你获得的带宽将是56/11*2=10.2Kbps,约1.27K字节/秒,将近原来的两倍。你同时打开的线程越多,你所获取的带宽就越大(原来是这样,以后每次我都通过1K个线程连接:P)。当然,这种情况下占用的机器资源也越多。有些号称“疯狂下载”的下载工具甚至可以同时打开100个线程连接服务器

多线程结构示意图:


多线程实现思路图:



代码实现,及思路解释:

线程类(服务器)

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

public class DownThread extends Thread{
	public int id;               //线程编号
	public URL url;              //文件下载的路径
	public File file;            //文件保存的路径
	public int singlethreadNum;  //每个下载的数据量
	
	
	public DownThread(int id, URL url, File file, int singlethreadNum) {
		super();
		this.id = id;
		this.url = url;
		this.file = file;
		this.singlethreadNum = singlethreadNum;
	}
	
	@Override
	public void run() {
		try {
			RandomAccessFile raf=new RandomAccessFile(file, "rwd");
			//分别计算每个下载的开始位置和结束位置
			int start=id*singlethreadNum;
			int end=(id+1)*singlethreadNum-1;
			//通过传过来的URL 获取下载的连接
			HttpURLConnection conn=(HttpURLConnection) url.openConnection();
			//设置下载超时值
			conn.setReadTimeout(5000);
			//设置一般请求属性
			conn.setRequestProperty("Range", "bytes="+start+"-"+end);
			//局部请求  状态码为206
			if(conn.getResponseCode()==206){
                       //随机写文件的时候从哪个位置开始写  
				raf.seek(start);//定位文件  
				//获取输入流
				InputStream is=conn.getInputStream();
				byte[] bytes=new byte[1024];
				int len=0;
				while((len=is.read(bytes, 0, bytes.length))!=-1){
					raf.write(bytes, 0, len);
				}
				raf.close();
				is.close();
			}
			
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
	
}

客户端类:

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

public class TestDown {
	public static void main(String[] args) {
		//设置线程数
		int threadnum=50;
		//下载路径
		String path="http://localhost:8080/web_project/images/s8.jpg";
		//httpurlconnection
		try {
			//获取下载地址
			URL url=new URL(path);
			//通过下载地址打开连接
			HttpURLConnection conn=(HttpURLConnection)url.openConnection();
			//设定请求方式
			conn.setRequestMethod("GET");
			//判断响应码是否为200  只有200的时候才会进入这个网页
			if(conn.getResponseCode()==200){
				//获取服务器中文件的大小
				int length=conn.getContentLength();
				//保存的文件路径
				File f=new File("C:/s8.jpg");
				//对随机的文件进行读写
				RandomAccessFile raf=new RandomAccessFile(f,"rwd");
				//设置下载文件大小
				raf.setLength(length);
				raf.close();
				//每个线程下载的数据量
				int singleThreadNum= length%threadnum==0 ? length/threadnum:length/threadnum+1;
					
				for (int i = 0; i < threadnum; i++) {
						new DownThread(i, url, f, singleThreadNum).start();
				}
				
			}else{
				System.out.println("网页错误");
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值