1

この質問が何度も聞かれるのを見ることができます。これを再度質問して申し訳ありません。奇妙な問題があります。

ExecutorService を介して何千ものジョブを個別の Runnable タスクとして送信するジョブがあります。これは単純な for ループで行われます。for ループの終わりで、service.shutdown() を呼び出し、続いて awaitTermination を呼び出します。

サブミットされるスレッドの数が膨大なため、すべてのタスクがサブミットされるまでスレッドがハングアップし続けます。

実行が終了するとすぐにこれらのスレッドを正常に終了できる方法はありますか?

4

2 に答える 2

0

shutdownNow()保留中のタスクで実行を中止できるのは正しいです。あなたの目標が結果を計算するのに十分なだけの作業を行うことであり (これには未定の数のタスクが必要です)、結果が得られたらすぐにそれ以上の作業をやめる場合、Runnableオブジェクトがループを停止する必要があることをループします。何かのようなもの:

ExecutorService svc = ...
AtomicBoolean done = new AtomicBoolean();
for (int i=0; i < jobs.length; i++) {
   svc.submit(new MyRunnable(done, jobs[i]));
   if (done.get()) break;
}

class MyRunnable implements Runnable {
   private final Whatever job;
   private final AtomicBoolean done;
   MyRunnable (AtomicBoolean done, Whatever job) { this.done = done;  this.job = job; }
   public void run() {
     if (done).get() return;
     //do the work
     if (somehowComputeThatTheWorkIsComplete) done.set(true);
   }
 }

あまりにも多くのスレッドが起動されているためにハングアップしている場合は、 Executors.newFixedThreadPool()の使用を検討してください。コンピューターは、実際には、利用可能な論理コアの数よりも多くの作業を同時に行うことはできません。そのため、無制限のスレッド プール (Integer.MAX_VALUEスレッドまで作成可能) を使用しても、実際には同時実行性が向上しないため、役に立ちません。エグゼキューターを妥当な数のスレッドに制限するだけで、「ハング」タイプの問題はおそらくなくなるでしょう。

于 2013-10-14T18:34:47.500 に答える