2011-07-01 3 views
1

私は非常によく似ているコードベースのどこか他の場所にあるマルチスレッドコードを持っていますが、ここで何がうまくいかないのかよく分かりません。Javaの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のサイズを増加させないことを保証できます。

+0

"処理結果"が何回表示されますか?あなたがデバッガで侵入したらどうなりますか? –

+0

whileループを永遠に実行しますか? 'index = getResultsIndex()'は何をしますか?たぶん0からsize-1までのインデックスを返すので、ループは決して残らないでしょうか? – Howard

+0

また、 'allResults'の宣言と' getResultsIndex() 'の実装を示してください。出力が表示されない場合は、デッドロックが発生します。 –

答えて

1

私はあなたの配列tasksthreadsの長さ(つまり、あなたのケースでは2)を持っていますが、allResultsあなたのリスト場合は、行の中でそれに

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

を複数の値を割り当てることを、それは事実に関連していると仮定2つ以上のエントリがあり、スレッドはArrayIndexOutOfBoundsExceptionによって停止されます。たぶんあなたはこれをキャッチしますが、あなたが提示したコードの外では正しく処理しません。

+0

それは、非常にありがとう! – Ina

0

無限ループを引き起こすすべてのループの後でgetResultsIndex()が更新されないようです。

+0

@Ina:これをテストするとどうなりますか? –

+0

元の投稿を編集してgetResultsIndex()を表示しました。なぜgetResultsIndex()が更新されないのか分かりません。同期され、無限大(または少なくともInteger.MAX_VALUEにカウントされますが、それはまだallResults.size()よりも大きいです)。 – Ina

0

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

+0

コードの編集済みの記事を参照してください。 – Ina

関連する問題