//這是主類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