Java多线程下载的实现方法

代码如下:

package cn.me.test;

import java.io.InputStream;

import java.io.RandomAccessFile;

import java.net.HttpURLConnection;

import java.net.URL;

/**

* 多线程下载

* 1:使用RandomAccessFile在任意的位置写入数据。

* 2:需要计算第一个线程下载的数据量,可以平均分配。如果不够平均时,

*    则直接最后一个线程处理相对较少的数据

* 3:必须要在下载之前准备好相同大小的文件,通过文件头获取

*/

public class MultiThreadDownload {

public static void main(String[] args) throws Exception {

//1:声明文件名和下载的地址

String fileName = "aa.rar";

String urlStr = "http://localhost:7777/day18";

//2:声明Url

URL url = new URL(urlStr+"/"+fileName);

//3:获取连接

HttpURLConnection con =

(HttpURLConnection) url.openConnection();

//4:设置请求方式

con.setRequestMethod("GET");

//5:获取请求头,即文件的长度

int length = con.getContentLength();//获取下载文件的长度,以计算每个线程应该下载的数据量。

//6:在指定的目录下,创建一个同等大小的文件

RandomAccessFile file = new RandomAccessFile("d:/a/"+fileName, "rw");//创建一个相同大小的文件。

//7:设置文件大小,占位

file.setLength(length);//设置文件大小。

file.close();

//8:定义线程个数

int size = 3;

//9:计算每一个线程应该下载多少字节的数据,如果正好整除则最好,否则加1

int block = length/size==0?length/size:length/size+1;//计算每个线程应该下载的数据量。

System.err.println("每个线程应该下载:"+block);

//10:运行三个线程并计算从哪个字节开始到哪一个字节结束

for(int i=0;i<size;i++){

int start = i*block;

int end = start+(block-1);//计算每一个线程的开始和结束字节。

System.err.println(i+"="+start+","+end);

new MyDownThread(fileName, start, end,url).start();

}

}

static class MyDownThread extends Thread{

//定义文件名

private String fileName;

//定义从何地开始下载

private int start;

//定义下载到哪一个字节

private int end;

private URL url;

public MyDownThread(String fileName,int start,int end,URL url){

this.fileName=fileName;

this.start=start;

this.end=end;

this.url=url;

}

@Override

public void run() {

try{

//11:开始下载

HttpURLConnection con =

(HttpURLConnection) url.openConnection();

con.setRequestMethod("GET");

//12:设置分段下载的请求头

con.setRequestProperty("Range","bytes="+start+"-"+end);//设置从服务器上读取的文件块。

//13:开始下载,需要判断206

if(con.getResponseCode()==206){//访问成功,则返回的状态码为206。

InputStream in = con.getInputStream();

//14:声明随机写文件对象,注意rwd是指即时将数据写到文件中,而不使用缓存区

RandomAccessFile out = new RandomAccessFile("d:/a/"+fileName,"rwd");

out.seek(start);//设置从文件的某个位置开始写数据。

byte[] b=new byte[1024];

int len = 0;

while((len=in.read(b))!=-1){

out.write(b,0,len);

}

out.close();

in.close();

}

System.err.println(this.getName()+"执行完成");

}catch(Exception e){

throw new RuntimeException(e);

}

}

}

}

(0)

相关推荐

  • Java多线程实现异步调用的方法

    在JAVA平台,实现异步调用的角色有如下三个角色:调用者 提货单   真实数据 一个调用者在调用耗时操作,不能立即返回数据时,先返回一个提货单.然后在过一断时间后凭提货单来获取真正的数据. 去蛋糕店买蛋糕,不需要等蛋糕做出来(假设现做要很长时间),只需要领个提货单就可以了(去干别的事情),等到蛋糕做好了,再拿提货单取蛋糕就可以了. public class Main { public static void main(String[] args) { System.out.println("ma

  • Java Web项目中使用Socket通信多线程、长连接的方法

    很多时候在javaweb项目中我们需要用到Socket通信来实现功能,在web中使用Socket我们需要建立一个监听程序,在程序启动时,启动socket监听.我们的应用场景是在java项目中,需要外接如一个硬件设备,通过tcp通信,获取设备传上来的数据,并对数据做回应. 先看一下web的监听代码: import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class

  • Java Socket实现多线程通信功能示例

    本文实例讲述了Java Socket实现多线程通信功能的方法.分享给大家供大家参考,具体如下: 前面的文章<Java Socket实现单线程通信的方法示例>说到怎样写一个最简单的Java Socket通信,但是文章中的例子有一个问题就是Server只能接受一个Client请求,当第一个Client连接后就占据了这个位置,后续Client不能再继续连接,所以需要做些改动,当Server没接受到一个Client连接请求之后,都把处理流程放到一个独立的线程里去运行,然后等待下一个Client连接请求

  • java多线程和并发包入门示例

    一.java多线程基本入门java多线程编程还是比较重要的,在实际业务开发中经常要遇到这个问题. java多线程,传统创建线程的方式有两种. 1.继承自Thread类,覆写run方法. 2.实现Runnable接口,实现run方法. 启动线程的方法都是调用start方法,真正执行调用的是run方法.参考代码如下: 复制代码 代码如下: package com.jack.thread; /** * 线程简单演示例子程序 *  * @author pinefantasy * @since 2013-

  • Java Socket实现单线程通信的方法示例

    本文实例讲述了Java Socket实现单线程通信的方法.分享给大家供大家参考,具体如下: 现在做Java直接使用Socket的情况是越来越少,因为有很多的选择可选,比如说可以用spring,其中就可以支持很多种远程连接的操作,另外jboss的remoting也是不错的选择,还有Apache的Mina等等,但是在有些时候一些特殊情况仍然逃脱不了直接写Socket的情况,比如公司内部一些莫名其妙的游戏规则. 废话不说了,下面就看看如果自己写Socket应该怎么做吧. 首先是写一个Server类,这

  • java基本教程之线程休眠 java多线程教程

    本章涉及到的内容包括:1. sleep()介绍2. sleep()示例3. sleep() 与 wait()的比较 1. sleep()介绍sleep() 定义在Thread.java中.sleep() 的作用是让当前线程休眠,即当前线程会从"运行状态"进入到"休眠(阻塞)状态".sleep()会指定休眠时间,线程休眠的时间会大于/等于该休眠时间:在线程重新被唤醒时,它会由"阻塞状态"变成"就绪状态",从而等待cpu的调度执行

  • Java多线程的用法详解

    1.创建线程 在Java中创建线程有两种方法:使用Thread类和使用Runnable接口.在使用Runnable接口时需要建立一个Thread实例.因此,无论是通过Thread类还是Runnable接口建立线程,都必须建立Thread类或它的子类的实例.Thread构造函数: public Thread( );  public Thread(Runnable target);  public Thread(String name);  public Thread(Runnable target

  • java多线程实现服务器端与多客户端之间的通信

    用java语言构建一个网络服务器,实现客户端和服务器之间通信,实现客户端拥有独立线程,互不干扰. 应用多线程来实现服务器与多线程之间的通信的基本步骤 服务器端创建ServerSocket,循环调用accept()等待客户端链接 客户端创建一个Socket并请求和服务器端链接 服务器端接受客户端请求,创建socekt与该客户端建立专线链接 建立链接的socket在一个单独的线程上对话 服务器继续等待新的链接 服务器端Server.java package test.concurrent.socke

  • java 多线程-线程通信实例讲解

    线程通信的目标是使线程间能够互相发送信号.另一方面,线程通信使线程能够等待其他线程的信号. 通过共享对象通信 忙等待 wait(),notify()和 notifyAll() 丢失的信号 假唤醒 多线程等待相同信号 不要对常量字符串或全局对象调用 wait() 通过共享对象通信 线程间发送信号的一个简单方式是在共享对象的变量里设置信号值.线程 A 在一个同步块里设置 boolean 型成员变量 hasDataToProcess 为 true,线程 B 也在同步块里读取 hasDataToProc

  • Java多线程中线程间的通信实例详解

    Java多线程中线程间的通信 一.使用while方式来实现线程之间的通信 package com.ietree.multithread.sync; import java.util.ArrayList; import java.util.List; public class MyList { private volatile static List list = new ArrayList(); public void add() { list.add("apple"); } publ

  • 深入理解JAVA多线程之线程间的通信方式

    一,介绍 本总结我对于JAVA多线程中线程之间的通信方式的理解,主要以代码结合文字的方式来讨论线程间的通信,故摘抄了书中的一些示例代码. 二,线程间的通信方式 ①同步 这里讲的同步是指多个线程通过synchronized关键字这种方式来实现线程间的通信. 参考示例: public class MyObject { synchronized public void methodA() { //do something.... } synchronized public void methodB()

随机推荐