1

コードベースの他の場所に非常によく似たマルチスレッドコードがあり、正常に機能しますが、ここで何が問題になっているのかよくわかりません。

これは、検索クエリの結果XMLを生成するための単純なマルチスレッドプロセスです。このメソッドを実行した結果は次のとおりです。

スレッドから戻る

System.out.println( "Finished multithreading loop");"という行に到達することはありません。

スレッドの数を変更しても効果はありません。

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のサイズを大きくしないことを保証できます。

4

3 に答える 3

1

配列tasksの長さがthreads(つまり、この場合は2)であるという事実に関連していると思いますが、行内でより多くの値を割り当てます。

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

リストallResultsに3つ以上のエントリがある場合、スレッドは。によって停止されますArrayIndexOutOfBoundsException。たぶんあなたはこれを捕まえますが、あなたが提示したコードの外でそれを適切に処理しません。

于 2011-07-01T15:51:05.283 に答える
0

getResultsIndex()は、ループごとに更新されていないため、無限ループになっているようです。

于 2011-07-01T14:41:55.363 に答える
0

allResultsとgetResultsIndexが何であるかはコードからは明らかではありませんが、getResultsIndexが返すものを更新することは決してないようです。

于 2011-07-01T14:52:31.497 に答える