获取到服务器端资源文件的大小(connection.getContentLength())
String path = "http://localhost:8080/ff.exe";
URL url = new URL(path);
// 获取链接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// 参数
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
// 响应码
int responseCode = connection.getResponseCode();
if (responseCode == 200) {
    // 得到服务端返回的文件大小
    long contentLength = connection.getContentLength();
    System.out.println("服务器文件大小:"+contentLength);
}
// 断开连接
connection.disconnect();
在本地创建一个大小和服务器一样的的空白文件
File file = new File("temp.ext");
RandomAccessFile raf= new RandomAccessFile(file, "rw");
raf.setLength(contentLength);
根据开启线程的数量,把服务器资源给等分成若干份(threadCount:线程数量)
假设文件大小是10个byte。(长度:length)
假设3个线程(线程数量:threadCount)。
 int blockSize = length / threadCount;
线程1 下载3个byte    1-3     0 * blockSize + 1 ~ 1 * blockSize
线程2 下载3个byte    4-6     1 * blockSize + 1 ~ 2 * blockSize 
线程3 下载4个byte    7-10    2 * blockSize + 1 ~ 3 * blockSize(length)
// 开启若干个子线程,分别去下载对应的资源
long threadCount = 3;
long blockSize = contentLength / threadCount;
for (int i = 1; i <= threadCount; i++) {
    // 计算下载起始、结束位置
    long startIndex = (i - 1) * blockSize + 0;// 服务器也是从0开始
    long endIndex = i * blockSize - 1; //
    // 最后一个线程
    if (i == threadCount) {
        endIndex = contentLength - 1;
    }
    System.out.println("开启线程:" + i + ",下载的位置:(" + startIndex + "~"
            + endIndex + ")");
    new DownloadThread(i, startIndex, endIndex, path).start();
}
创建线程类
static class DownloadThread extends Thread {
    private int threadId;
    private long startIndex;
    private long endIndex;
    private String path;
    public DownloadThread(int threadId, long startIndex, long endIndex,
            String path) {
        super();
        this.threadId = threadId;
        this.startIndex = startIndex;
        this.endIndex = endIndex;
        this.path = path;
    }
    public void run() {
        URL url;
        try {
            url = new URL(path);
            // 获取链接
            HttpURLConnection connection = (HttpURLConnection) url
                    .openConnection();
            // 参数
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(5000);
            // 告诉服务器下载的参数
            connection.setRequestProperty("Range", "bytes=" + startIndex
                    + "-" + endIndex);
            // 响应码
            int responseCode = connection.getResponseCode();
            System.out.println("服务器状态码:" + responseCode);
            // 下载服务器文件,返回的是206
            if (responseCode == 206) {
                InputStream inputStream = connection.getInputStream();
                File file = new File("temp.exe");
                RandomAccessFile raf = new RandomAccessFile(file, "rw");
                // 指定文件开始写的位置
                raf.seek(startIndex);
                System.out.println("第" + threadId + "个线程,写文件的开始、结束位置("
                        + (startIndex) + "," + (endIndex) + ")");
                int len = 0; 
                byte[] buf = new byte[1024];
                while ((len = inputStream.read(buf)) != -1) {
                    raf.write(buf, 0, len);
                }
                inputStream.close();
                raf.close();
                System.out.println("第" + threadId + "个线程下载完毕了");
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
原文:http://blog.csdn.net/biezhihua/article/details/42045805