使用ExecutorService的Java中的多线程代码无法返回,为什么?

时间:2011-07-01 14:35:19

标签: java multithreading executorservice

我的代码库中的其他地方有非常类似的多线程代码可以正常工作,但我看不出这里出了什么问题。

这是一个简单的多线程进程,可以为搜索查询生成一些结果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的大小。

3 个答案:

答案 0 :(得分:1)

我认为这与事实相关,即您的数组tasks的长度为threads(即您的情况为两个),但您在行中为其指定了更多值

for (int i = 0; i < allResults.size(); i++) {
    tasks[i] = ...
    ....
}

如果您的列表allResults包含两个以上的条目,则ArrayIndexOutOfBoundsException将阻止您的主题。也许你抓住了这个但是在你提交的代码之外没有正确处理它。

答案 1 :(得分:0)

看起来getResultsIndex()在每次循环后都没有更新,导致无限循环。

答案 2 :(得分:0)

从你的代码中不清楚allResults和getResultsIndex是什么,但你似乎永远不会更新getResultsIndex返回的内容。