多线程下载网络资源
2015-03-11 23:43
183 查看
创建多个线程在单位时间内便可以获得更多的服务端资源,可以加快下载速度。但是也并不是线程越多越好,假设我们在客户端新建了10000个线程,此时服务端的CPU就会在线程间的轮询切换上消耗大量的时间,而真正用来下载数据资源的时间就会减少。同时,由于客户端和服务端物理带宽的限制,下载速度也会受到极大的关联。
下面我将用多线程下载网络上的资源,代码如下:
如果在有足够带宽的情况下,适当增加线程的个数,确实是加快了下载的速度。
下面我将用多线程下载网络上的资源,代码如下:
package hxl.insist.two; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL; import java.util.concurrent.CountDownLatch; /** * 多线程从网络服务器上下载资源 * @author Hanxl */ public class MultiThreadDownload { /** * 下载的线程数量 */ private int threadCount; /** * 资源的Url路径 */ private String resourcePath; /** * 保存到本地的文件名 */ private String fileName; /** * 锁存器,判断所有子线程是否运行完毕 */ final CountDownLatch cdl = new CountDownLatch(threadCount); public MultiThreadDownload(int threadCount,String resourcePath,String fileName) { this.threadCount = threadCount; this.resourcePath = resourcePath; this.fileName = fileName; } /** * 在本地创建一个和网络资源相同大小的文件 * @return 网络资源文件大小 */ private int createLocalFile() throws Exception { URL url = new URL(resourcePath); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //将请求方式设为Get conn.setRequestMethod("GET"); //设置请求超时时间 conn.setConnectTimeout(5000); //获取响应的状态码 int statusCode = conn.getResponseCode(); int resourceSize = 0; if(statusCode == 200) { //取得网络资源文件的大小 resourceSize = conn.getContentLength(); //在本地创建一个和网络资源相同大小的文件 RandomAccessFile localFile = new RandomAccessFile(fileName, "rw"); localFile.setLength(resourceSize); } return resourceSize; } /** * 创建线程并从网络上开始下载资源 */ private void createThreadAndDownload(final int startIndex,final int endIndex) { new Thread(new Runnable() { @Override public void run() { try { URL url = new URL(resourcePath); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); //为服务器指定下载的资源是哪一部分 conn.setRequestProperty("Range", "bytes=" + startIndex + "-"+endIndex); //206表示请求部分数据成功 int code = conn.getResponseCode(); if(code == 206) { RandomAccessFile localFile = new RandomAccessFile(fileName, "rw"); InputStream is = conn.getInputStream(); localFile.seek(startIndex); System.out.println(Thread.currentThread().getName() + " : " + "开始下载" + startIndex + "---" + endIndex); int len = -1; byte[] bufferArea = new byte[1024]; while((len = is.read(bufferArea)) != -1) { localFile.write(bufferArea, 0, len); } is.close(); localFile.close(); //递减锁存器的计数,如果计数到达零,则释放所有等待的线程。 cdl.countDown(); System.out.println(Thread.currentThread().getName() + " : " + "下载完毕"); } } catch (Exception e) { e.printStackTrace(); } finally { } } }).start(); } /** * 让程序开始从网络上下载资源 */ public void startDownload() throws Exception { int resourceSize = createLocalFile(); if(resourceSize != 0) { //将资源大小按线程数量等分 int resourceAverageSize = resourceSize / threadCount; for(int threadIndex = 0;threadIndex < threadCount;threadIndex++) { //为每个线程指定下载位置 final int startIndex = threadIndex * resourceAverageSize; int endIndex = startIndex + resourceAverageSize - 1; if(threadIndex == (threadCount - 1)) { endIndex = resourceSize - 1; } createThreadAndDownload(startIndex,endIndex); } } while (true) { //直到锁存器倒计数至零之前一直等待 cdl.await(); break; } } public static void main(String[] args) { try { if(args.length == 3) { MultiThreadDownload mtd = new MultiThreadDownload(Integer.parseInt(args[0]),args[1],args[2]); mtd.startDownload(); } } catch (Exception e) { e.printStackTrace(); } } }
如果在有足够带宽的情况下,适当增加线程的个数,确实是加快了下载的速度。
相关文章推荐
- Java之多线程下载网络资源
- Java多线程下载网络资源
- java多线程下载网络资源(支持断点续传)
- 网络通信2-多线程下载网络资源
- HttpUrlConnection实现多线程下载网络资源
- [Android]网络资源下载时断点续传的实现
- 网络下载资源导航帖
- Android(五)数据存储之五网络多线程断点下载
- 畅游电驴/电骡(emule) 1.0 发布-下载网络资源的利器
- 网络资源下载
- Android(五)数据存储之五网络多线程断点下载-世事如棋,乾坤莫测,笑 ...  -  棒槌网@Android开发论坛 - Powered by
- 网络多线程断点下载
- java实现多线程下载网络文件
- android下载问题。本地与网络资源大小不一致解决方法
- java 下载网络资源的源码供参考
- 网络多线程断点下载
- 常用软件下载地址(网络资源无限)
- 为什么象网络蚂蚁这样的多线程程序可以加快下载速度?
- Android 数据存储之五网络多线程断点下载