2016-08-04 46 views
1

我想我的手在多线程,并希望实现一个小程序,以同时下载多个文件。 我创建了一个扩展Thread的FileDownloader类。java - 线程IllegalThreadStateException当下载多个文件

从主,我的想法是创建一个有问题的所有FileDownload对象的ArrayList(allDownloads),并呼吁activeDownloads另一个ArrayList的,我在那里限制对活动的下载的大写金额为4

程序下载几个文件,然后抛出这个异常。我明白,它试图再次启动一个线程时抛出。但在下面的程序中,我打断了一个线程,并在每次文件下载完成时启动另一个线程,所以我不明白,我怎么可能启动同一线程?

while (allDownloads.size() > 0) { 
      while (activeDownloads.size() < 4) { 
       if (allDownloads.iterator().hasNext()) { 
        FileDownloader d = allDownloads.iterator().next(); 
        activeDownloads.add(d); 
        allDownloads.remove(d); 

       } 
      } 
      for (int i = 0; i < activeDownloads.size(); i++) { 
       FileDownloader t = activeDownloads.get(i); 
       try { 
        if (!t.isRunning()) 
         t.start(); 
        else if (t.isFinished()) { 
         t.interrupt(); 
         activeDownloads.remove(t); 
        } 
       } catch (IllegalThreadStateException e) { 
        System.out.println("****Thread cannot be restarted****"); 
       } 
      } 

     } 

感谢所有帮助

+1

你可以把异常消息请catch子句中添加e.printStackTrace(),所以我们可以清楚地看到发生了什么 –

+0

是的:把一个的println到您的catch块甚至不能打印e的消息,这比空的catch块好不了多少。所以,一些失败,但为什么要说什么...... – GhostCat

+0

什么是't.isRunning()'方法?我不认为它是'Thread' api的一部分。 – Codebender

回答

0

您从activeDownloads而迭代它删除元素。尽量向后遍历List

for (int i = activeDownloads.size()-1 ; i >=0 ; i--) {...} 

这样,你的指数仍然是正确的,当你删除元素形成List

+0

这不是问题的根源,当然他可以在遍历容器列表时删除元素,但是我没有看到任何问题! –

+0

是的,但索引将是不正确的。 也就是说,当你移除List的第二个元素时,第三个元素将变成第二个元素等等。所以你的下一个get(i)将引用一个意外的元素。 – garnulf

+0

应该生成一个IllegalThreadStateException异常我不这么认为? –

1

你的错误可能是此:

if (allDownloads.iterator().hasNext()) { 
    FileDownloader d = allDownloads.iterator().next(); 
    ... 
} 

你都应该请将allDownloads.iterator()的值保存在专用变量中,否则您将在每次调用时创建一个新的迭代器,然后始终获得第一个值,以便在此处使用相同的线程。

因此,代码应该是:

Iterator<FileDownloader> it = allDownloads.iterator(); 
while (activeDownloads.size() < 4) { 
    if (it.hasNext()) { 
     FileDownloader d = it.next(); 
     activeDownloads.add(d); 
     it.remove(); 

    } 
}