web-dev-qa-db-ja.com

Java executorクラスのすべての実行可能なスレッドを停止する方法は?

final ExecutorService executor = Executors.newFixedThreadPool(1);
final Future<?> future = executor.submit(myRunnable);
executor.shutdown();
if(executor.awaitTermination(10, TimeUnit.SECONDS)) {
  System.out.println("task completed");
}else{
  System.out.println("Executor is shutdown now");
}

//MyRunnable method is defined as task which I want to execute in a different thread.

Executorクラスのrunメソッドは次のとおりです。

public void run() {
try {
     Thread.sleep(20 * 1000);
} catch (InterruptedException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
}}

ここでは20秒待機していますが、コードを実行すると例外がスローされます。

Java.lang.InterruptedException: sleep interrupted
at Java.lang.Thread.sleep(Native Method)

Java Executor classで台無しになっている並行スレッドを閉じることができません。これが私のコードフローです:

  • Java executorクラスを使用して新しいスレッドを作成し、MyRunnableで記述されたタスクを実行します
  • executorタスクが完了するまで10秒待ちます。
  • タスクが完了すると、実行可能なスレッドも終了します。
  • タスクが10秒以内に完了しない場合、executorクラスはスレッドを終了する必要があります。

最後のシナリオでのタスクの終了を除いて、すべてが正常に機能します。どうすればよいですか?

14
Amit Pal

shutDown() メソッドは、追加のタスクがスケジュールされないようにするだけです。代わりに、 shutDownNow() を呼び出して、Runnableでスレッドの中断を確認できます。

// in your Runnable...
if (Thread.interrupted()) {
  // Executor has probably asked us to stop
}

コードに基づく例は次のようになります。

final ExecutorService executor = Executors.newFixedThreadPool(1);
executor.submit(new Runnable() {
  public void run() {
    try {
      Thread.sleep(20 * 1000);
    } catch (InterruptedException e) {
      System.out.println("Interrupted, so exiting.");
    }
  }
});

if (executor.awaitTermination(10, TimeUnit.SECONDS)) {
  System.out.println("task completed");
} else {
  System.out.println("Forcing shutdown...");
  executor.shutdownNow();
}
16
Duncan Jones

スレッドの現在の状態がわからないため、実行中のスレッドを外部から終了することは一般に悪い考えです。いくつかのクリーンアップを行う必要がある可能性があります。強制的にシャットダウンします。 そのため、それを行うThreadのすべてのメソッドは非推奨としてマークされています

プロセス間通信で使用できる多くの手法の1つを使用して、スレッド自体で実行されているプロシージャに、その作業を中止して正常に終了する必要があることを通知することをお勧めします。これを行う1つの方法は、abort()メソッドをランナブルに追加し、volatileとして宣言されたフラグを立てることです。 Runnableの内部ループはそのフラグをチェックし、そのフラグが立てられたときに(制御された方法で)終了します。

2
Philipp