Java多線程下載的基礎類,類似於迅雷,QQ旋風等下載器一樣的原理。
package com.shenzhen.mutiledownload2014;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* 測試多線程下載的樣例
*
* @author mayubao
*
*/
public class TestDownload {
public static final String path = "http://192.168.1.120:8080/a.zip";
public static final void main(String[] args) throws Exception {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();// 打開一個鏈接
// 設置一個請求的相關信息
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
// User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0)
// Gecko/20100101 Firefox/29.0
conn.setRequestProperty("User-Agent",
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0");
int code = conn.getResponseCode();
if (code == 200) {// 請求過去且回復內容正常的話
int len = conn.getContentLength();
RandomAccessFile file = new RandomAccessFile("D:/temp/test/"
+ getFileName(path), "rwd");
// 1.創建一個本地文件跟服務器的大小一致
file.setLength(len);
// 2.根據服務器中要下載的文件大小劃分要多少個線程
int threadnum = 3;
int blocksize = len / threadnum;
/**
* 多線程下載 線程1 0 ~ blocksize 線程2 blocksize*1 ~ blocksize*2 線程3
* blocksize*2 ~ len
*/
for (int i = 0; i < threadnum; i++) {
int startposition = i * blocksize;
int endposition = (i + 1) * blocksize;
if (i == (threadnum - 1)) {// 最後一個線程的話,那麼就另endposition=len
endposition = len;
}
// 分別執行每一個線程
new DownloadTask(i, path, startposition, endposition).start();
}
}
// conn.setRequestProperty(key, value);
}
public static String getFileName(String path) {
int start = path.lastIndexOf("/");
return path.substring(start, path.length());
}
}
/**
* 下載的線程類
*
* @author mayubao
*
*/
class DownloadTask extends Thread {
private int id;
private String path;
private int startposition;
private int endposition;
public DownloadTask(int id, String path, int startposition, int endposition) {
this.id = id;
this.path = path;
this.startposition = startposition;
this.endposition = endposition;
}
@Override
public void run() { // 每一個線程體要執行的內容
URL url;
try {
url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 設置一個請求的相關信息
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
// User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0)
// Gecko/20100101 Firefox/29.0
conn.setRequestProperty("User-Agent",
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0");
InputStream is = conn.getInputStream();
RandomAccessFile file = new RandomAccessFile(getFileName(path),
"rwd");
file.seek(startposition);
// 將反饋回來的輸入流寫到RandomAccessFile裡面去
byte[] buffer = new byte[1024];
int len = 0;
while ((len = is.read(buffer)) != -1) {// 輸入流沒到盡頭
file.write(buffer, 0, len);
}
file.close();
System.out.println("第" + id + "個線程已經下載完成了");
} catch (Exception e) {
e.printStackTrace();
}
super.run();
}
public static String getFileName(String path) {
int start = path.lastIndexOf("/");
return path.substring(start, path.length());
}
}
Java1.5後的多線程框架 http://www.linuxidc.com/Linux/2014-02/96879.htm
Java多線程和同步的理解 http://www.linuxidc.com/Linux/2013-12/93691.htm
Java中兩種實現多線程方式的對比分析 http://www.linuxidc.com/Linux/2013-12/93690.htm
Java利用多線程計算目錄數據大小 http://www.linuxidc.com/Linux/2013-09/90715.htm
Java多線程向數據庫寫入數據 http://www.linuxidc.com/Linux/2013-09/90297.htm
Java多線程經典案例 http://www.linuxidc.com/Linux/2014-06/103458.htm