java多线程下载的问题?

「已注销」 2013-12-07 08:46:53
各位大虾,我刚学java,按照书上的自己写了一个多线程下载的工具,但是运行时却没有同时运行多个线程,而是顺序运行的。
main函数中已经将下载划分为2个线程下载:

DThreadtasks=new DThread[max_num];
for(int i=0;i<max_num;i++){
long start=i*perLen;
RandomAccessFile currentPart=new RandomAccessFile(destFileName,"rwd");
currentPart.seek(start);
tasks[i]=new DThread(i,strUrl,currentPart,start,perLen,0);
tasks[i].start();
}


下载线程代码如下:

public class DThread extends Thread {
String strUrl=null;
URL url=null;
int id;
RandomAccessFile destFile=null;
long size=0;
long startPart;
long hasRead=0;
long startPos;
public DThread(int id,String src,RandomAccessFile destFile,long start,long length,long hasRead){
this.id=id;
this.strUrl=src;
this.destFile=destFile;
this.size=length;
this.startPart=start;
this.hasRead=hasRead;

this.startPos=this.startPart+this.hasRead;
}

public long getHasRead(){
return this.hasRead;
}

@Override
public void run() {
// TODO Auto-generated method stub
super.run();
try {
// destFile.seek(startPos);
System.out.println("Thread-"+id+" started.");
Thread.sleep(1000);
url=new URL(strUrl);
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
conn.setReadTimeout(50000);
conn.setRequestMethod("GET");
InputStream ins=conn.getInputStream();
ins.skip(startPos);
byte[] buffer = new byte[DTask.BUFFER_SIZE];
int read=0;

while(hasRead<size && (read=ins.read(buffer))!=-1){
destFile.write(buffer, 0, read);
hasRead+=read;
System.out.println("Thread-"+id+" has Read "+hasRead);
}

destFile.close();
ins.close();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
mkLogger logger=new mkLogger("DThread");
logger.log("Error URL:"+strUrl);
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}




运行后,结果是
Thread-0先下载50%,然后Thread-1才开始下载剩下的50%。而不是同时下载的。半天不知道怎么回事,求解?
...全文
253 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
「已注销」 2013-12-12
  • 打赏
  • 举报
回复
引用 5 楼 baiyewu19 的回复:
[quote=引用 4 楼 yanmengkui 的回复:] [quote=引用 2 楼 baiyewu19 的回复:] 看你的代码应该没问题,请问,System.out.println("Thread-"+id+" started.")你的这个打印,第2个线程启动是不是都在第一个线程下载结束才执行呢?
是啊!有时是在第一个线程执行的快结束的时候才开始下载。我测试用的下载的文件有100M左右。每次都是这样。用5个线程的时候,也是一个一个地下载。[/quote] “rwd” 打开以便读取和写入,对于 “rw”,还要求对文件内容的每个更新都同步写入到底层存储设备,估计是这个同步导致的,你使用“rw”模式试试[/quote] 谢谢你的回答,我已经找到了原因了。应该是InputStream引起的阻塞。添加下面的代码之后就OK了。
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");
			conn.setRequestProperty("Range", "bytes="+startPos+"-"+(startPos+currentSize-1));
baiyewu19 2013-12-08
  • 打赏
  • 举报
回复
看你的代码应该没问题,请问,System.out.println("Thread-"+id+" started.")你的这个打印,第2个线程启动是不是都在第一个线程下载结束才执行呢?
baiyewu19 2013-12-08
  • 打赏
  • 举报
回复
引用 4 楼 yanmengkui 的回复:
[quote=引用 2 楼 baiyewu19 的回复:] 看你的代码应该没问题,请问,System.out.println("Thread-"+id+" started.")你的这个打印,第2个线程启动是不是都在第一个线程下载结束才执行呢?
是啊!有时是在第一个线程执行的快结束的时候才开始下载。我测试用的下载的文件有100M左右。每次都是这样。用5个线程的时候,也是一个一个地下载。[/quote] “rwd” 打开以便读取和写入,对于 “rw”,还要求对文件内容的每个更新都同步写入到底层存储设备,估计是这个同步导致的,你使用“rw”模式试试
「已注销」 2013-12-08
  • 打赏
  • 举报
回复
引用 2 楼 baiyewu19 的回复:
看你的代码应该没问题,请问,System.out.println("Thread-"+id+" started.")你的这个打印,第2个线程启动是不是都在第一个线程下载结束才执行呢?
是啊!有时是在第一个线程执行的快结束的时候才开始下载。我测试用的下载的文件有100M左右。每次都是这样。用5个线程的时候,也是一个一个地下载。
「已注销」 2013-12-08
  • 打赏
  • 举报
回复
引用 1 楼 zcw20101 的回复:
看你的代码,每个线程执行一次都会sleep(1000),第一个线程启动后,在启动第二个线程的过程中会先sleep,而此时第一个线程正在下载,开始的时候当然肯定不会是同时的了,不过等所有线程都启动后,就是同时下载了
我将sleep注释掉之后,还是一样的。并没有同时进行。在两个线程执行完: System.out.println("Thread-"+id+" started."); 之后,第一个线程先下载50%,第二个线程才启动下载。是不是因为两个线程同时往同一个文件(RandomAccessFile)写内容,会引起阻塞啊?
zcw_1985 2013-12-07
  • 打赏
  • 举报
回复
看你的代码,每个线程执行一次都会sleep(1000),第一个线程启动后,在启动第二个线程的过程中会先sleep,而此时第一个线程正在下载,开始的时候当然肯定不会是同时的了,不过等所有线程都启动后,就是同时下载了

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧