我正在尝试多线程,并希望实现一个小程序来同时下载多个文件。 我创建了一个扩展Thread的FileDownloader类。
从主要方面来说,我的想法是创建一个包含所有FileDownload对象的ArrayList(allDownloads)和另一个名为activeDownloads的ArrayList,我将活动下载的amout限制为4。
程序下载一些文件然后抛出此异常。我知道在尝试再次启动Thread时会抛出它。但是在下面的程序中,每次文件下载完成时我都会打断一个线程并启动另一个线程,所以我不明白,我怎么能尝试启动SAME线程?
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****");
}
}
}
感谢您的帮助
答案 0 :(得分: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();
}
}
答案 1 :(得分:0)
您正在迭代它时从activeDownloads中删除元素。尝试向后迭代List
for (int i = activeDownloads.size()-1 ; i >=0 ; i--) {...}
这样,当您从List