//这是主类java
package pxy.s2.mutithead; import java.net.; import java.io.; public class MutiThread {json
/**** * 多线程的下载 * 在客服端采用多条线程进行下载 * 效率会高不少 * 多线程的关键步骤有: * 首先读取网络资料的大小:根据其大小也在本地建立一个同样大小的文件 * A:计算每一个线程的下载开始和结束点:好比:假如咱们客服端开启5个线程进行 * 下载:则每一个线程的负责的段有:资源的长度/线程数=每一个线程的负责下载的段 * 假设这里有5个线程id,从0--4--依次开始负责下载本身的段 * 则有: int start=i*block; * int end=(i+1)*block -1; * 因此各个线程只负责其下载--不关联其余的线程 * */ public static void main(String[] args) throws Exception{ //要下载的网络资料路径 String path="http://127.0.0.1:8080/json/StarUML.rar"; MutiThread.load(path,9); } private static void load(String path,int t) throws Exception{ URL url = new URL(path); HttpURLConnection con=(HttpURLConnection)url.openConnection(); con.setRequestMethod("GET");//设置请求的方法 con.setReadTimeout(5000);//设置连接的时间 int len=con.getContentLength();//获取网络资源的长度 File file = new File(MutiThread.getContentName(path));//建立一个本地文件,并和网络资源文件的大小同样 RandomAccessFile af = new RandomAccessFile(file, "rwd"); af.setLength(len);//设置本地文件的大小和网络资源同样大 int block=(len%t)==0?len/t:len/t+1;//获取每一个线程负责的下载的区域 /*** * 如下是开启线程进行下载任务 * 根据传来的线程数T进行开启 */ for(int i=0;i<t;i++){ new DownLoad(i,file,url,block).start(); } } private static String getContentName(String path) { return path.substring(path.lastIndexOf("/")+1); }
}网络
//如下是子类 package pxy.s2.mutithead;多线程
import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL;dom
public class DownLoad extends Thread{this
private int i;//标识一个线程的ID private File file;//本地文件 private URL url;//负责连接的URL private int block;//每一个线程下载的块的大小 public DownLoad(int i, File file, URL url, int block) { this.i=i; this.file=file; this.url=url; this.block=block; } public void run(){ /*** * 开始进行下载的处理 */ int start=i*block; int end=(i+1)*block-1; try { HttpURLConnection con = (HttpURLConnection)url.openConnection(); con.setReadTimeout(5000); con.setRequestMethod("GET"); con.setRequestProperty("Range", "bytes="+start+"-"+end);//设置头字段--根据其下载的区域设置 //建立一个随机file RandomAccessFile af = new RandomAccessFile(file,"rwd"); af.seek(start);//在这里写入数据 if(con.getResponseCode() == 206){//多线程下载的返回状态码为:206--不是200 InputStream in = con.getInputStream(); byte buf[] = new byte[1024]; int len=0; while((len=in.read(buf))!=-1){ af.write(buf,0,len); } af.close(); in.close(); System.out.println("第"+i+"线程下载完成"); }else{ System.out.println("第"+i+"线程没有完成下载"); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
}url