LoginSignup
2
3

More than 3 years have passed since last update.

JavaのExecutorServiceを正しく終了する

Posted at

コード

ExecutorServiceを停止するユーティリティ的な(Kotlin)

object ExecutorServiceUtils {

  val log by logger()

  /**
   * [ExecutorService]を正しく終了する。
   * 実行中のタスクがある場合は終了を待機する。
   * 一定時間待機しても終了しないタスクがある場合はキャンセル(interrupt)しようとする。
   *
   * @param pool          [ExecutorService]
   * @param waitTimeout   実行中のタスクの待機時間
   * @param cancelTimeout 実行中のタスクをキャンセルするときの待機時間
   */
  fun shutdownAndAwaitTermination(
      pool: ExecutorService,
      waitTimeout: Duration,
      cancelTimeout: Duration
  ) {
    pool.shutdown() // 新しいタスクの受付を停止
    try {
      // 実行中のタスクの終了を待機
      if (!pool.awaitTermination(waitTimeout.toMillis(), TimeUnit.MILLISECONDS)) {
        // 待機がタイムアウトしたとき
        log.warn("一定時間待機したが終了しないタスクがあるので、実行中のタスクをキャンセルする")
        pool.shutdownNow() // 実行中のタスクをキャンセルする
        // 実際に停止するまでもう一回待機
        if (!pool.awaitTermination(cancelTimeout.toMillis(), TimeUnit.MILLISECONDS)) {
          // 待機がタイムアウトしたとき
          log.warn("実行中のタスクをキャンセルできない")
        }
      }
    } catch (ie: InterruptedException) {
      // 現在のスレッドが割り込みされたとき、実行中のタスクを(もう一度)キャンセルしておく
      pool.shutdownNow()
      // interruptedのステータスを保持
      Thread.currentThread().interrupt()
    }
  }
}

解説

shutdown()

シャットダウンを開始する

  • 新しいタスクを受け付けないようになる
  • 実行中のタスクがある場合はそのまま実行される
  • 実行中のタスクの完了を待機しない。待機したい場合はawaitTerminationを使う

awaitTermination(long, TimeUnit)

実行中のタスクが終了するまで待機する(処理をブロックする)

  • 実行中のタスクがない場合は特になにもしない
  • 指定したタイムアウト時間経っても終了しない場合はfalseを返す
  • 待機している間に現在のスレッドに対して割り込み(interrupt)があった場合はInterruptedExceptionがスローされる

shutdownNow()

実行中のタスクの停止(キャンセル)を試みる

  • タスクを停止できるとは限らない(Thread.interrupt()するだけなので。タスク側の処理を停止可能なように作っておく必要がある)
  • 停止完了まで待機しない。待機したい場合はawaitTerminationを使う

このサンプルコードの注意点

1つのアプリケーションの中で複数のExecutorServiceを扱う場合、サンプルコードのログ出力ではどのExecutorServiceに関するログなのか判断できない。

参考

ExecutorService (Java Platform SE 8)

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3