如果没有加同步块虽然下载完毕的文件是正确的但是进度确实99%,加了同步块之后就是100%了。想了好几天没想出来到底是哪里出了同步问题。加法不应该会有同步问题啊?
- package com.java.test;
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.RandomAccessFile;
- import java.net.HttpURLConnection;
- import java.net.MalformedURLException;
- import java.net.URL;
- public class UpdateReceiver {
- private static int length=0;
- private RandomAccessFile accessFile;
- private static Object object=new Object();
- public static void main(String[] args) {
- new UpdateReceiver().download("http://gdown.baidu.com/data/wisegame/3cf61f0c7216ed52/UCliulanqi_90.apk",3); // 开启三条线程进行文件的下载
- }
- /**
- * 多线程下载文件
- *
- * @param path
- * 网络文件URL
- * @param threadNum
- * 开启的线程数
- */
- public void download(String path, int threadNum) {
- try {
- URL url = new URL(path);
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setConnectTimeout(3000);
- conn.setRequestMethod("GET");
- if (conn.getResponseCode() == 200) {
- int fileLength = conn.getContentLength(); // 获取网络文件大小
- File file = new File("d://a", "b.exe");
- accessFile = new RandomAccessFile(file, "rwd");
- accessFile.setLength(fileLength); // 在本地生成相同大小的一个文件 }
- int block = fileLength % threadNum == 0 ? fileLength/ threadNum : (fileLength / threadNum) + 1; // 每条线程负责下载的数据量
- for (int threadId = 0; threadId < threadNum; threadId++) {
- new DownloadThread(threadId, block, path, file).start();
- }
- }
- } catch (MalformedURLException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- public class DownloadThread extends Thread {
- private int threadId;
- private int block;
- private String path;
- private File file;
- public DownloadThread(int threadId, int block, String path, File file) {
- this.threadId = threadId;
- this.block = block;
- this.path = path;
- this.file = file;
- }
- public void run() {
- super.run();
- int start = threadId * block; // 计算线程从网络文件哪一处开始下载
- int end = (threadId + 1) * block - 1; // 计算线程下载到网络文件的什么位置
- InputStream in = null;
- RandomAccessFile accessFile = null;
- try {
- accessFile = new RandomAccessFile(file, "rwd");
- accessFile.seek(start);
- URL url = new URL(path);
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setConnectTimeout(3000);
- conn.setRequestMethod("GET");
- conn.setRequestProperty("Range", "bytes=" + start + "-" + end);// 设置该头字段表示下载一部分数据
- if (conn.getResponseCode() == 206) {// 请求范围时返回码应为206
- in = conn.getInputStream();
- byte[] buffer = new byte[1024];
- int len = 0;
- while ((len = in.read(buffer)) != -1) {
- synchronized (object) {
- accessFile.write(buffer,0, len);
- length+=len;
- System.out.println(length*100/accessFile.length()+"%");
- }
- }
- }
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- try {
- System.out.println("length:"+length);
- System.out.println("第"+(threadId+1)+"条线程下载完毕");
- if (accessFile != null && in != null) {
- accessFile.close();
- in.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
复制代码
|