我的代码库中的其他地方有非常类似的多线程代码可以正常工作,但我看不出这里出了什么问题。
这是一个简单的多线程进程,可以为搜索查询生成一些结果XML。运行此方法的输出是:
从线程返回
System.out.println行(“已完成的多线程循环”);“永远不会到达。
修改线程数无济于事。
private void fillAllResults() {
int threads = 2;
final FutureTask[] tasks = new FutureTask[threads];
final ExecutorService executor = Executors.newCachedThreadPool();
for (int i = 0; i < allResults.size(); i++) {
tasks[i] = new FutureTask<Integer>(new Callable<Integer>() {
public Integer call() throws Exception {
int index;
while ((index = getResultsIndex()) < allResults.size()) {
System.out.println("Processing result " + index);
Result result = allResults.get(index);
fillResultXML(result);
}
System.out.println("Returning from threads");
return 1;
}
});
executor.execute(tasks[i]);
}
for (int i = 0; i < threads; i++) {
try {
tasks[i].get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
executor.shutdown();
System.out.println("Finished multithreading loop");
}
编辑,感谢所有人的快速回复!这是答案:
它显示'处理结果'的次数和我的结果一样多。如果allResults.size()为25,则显示处理结果1,处理结果2 ...处理结果24。
这是缺少的额外代码:
private List<Result> allResults = new ArrayList<Result>();
private int resultsIndex = 0;
private synchronized int getResultsIndex() {
return resultsIndex++;
}
如果有人想知道,我可以保证循环中的代码都不会增加allResults的大小。
答案 0 :(得分:1)
我认为这与事实相关,即您的数组tasks
的长度为threads
(即您的情况为两个),但您在行中为其指定了更多值
for (int i = 0; i < allResults.size(); i++) {
tasks[i] = ...
....
}
如果您的列表allResults
包含两个以上的条目,则ArrayIndexOutOfBoundsException
将阻止您的主题。也许你抓住了这个但是在你提交的代码之外没有正确处理它。
答案 1 :(得分:0)
看起来getResultsIndex()在每次循环后都没有更新,导致无限循环。
答案 2 :(得分:0)
从你的代码中不清楚allResults和getResultsIndex是什么,但你似乎永远不会更新getResultsIndex返回的内容。