multi thread 10

Two-Phase Termination パターン

二段階の終了.きちんと終了処理をして実行を終える,gracefulな終了を行う.

スレッドの作業中に別のスレッドから終了要求を受け取ったこのスレッドは,いきなり終了せず必要な後片付けを始め,終了処理中状態になる.そして終了処理が完了すると,今度こそ本当にスレッドが終了する.

public class Terminator extends Threads {
    private volatile boolean shutdownRequested = false;
    public void shutdownRequest() {
        shutdownRequested = true;
        interrupt();
    }
    public boolean isShutdownRequested() {
        return shutdownRequested;
    }
    public final void run() {
        try {
            while (!isShutdownRequested()) {
                doWork();
            }
        } catch (InterruptedException e) {
        } finally {
            isShutdown();
        }
    }
}
  • Threadクラスのstopは使わない(インスタンスの安全性が失われる)
  • フラグのテストだけでは不十分(interruptすることで,そのスレッドがsleepしていた場合も中断させることができる)
  • インタラプト状態のテストだけでも不十分(InterruptedExceptionが投げられた場合はインタラプト状態でなくなる→shutdownRequestが出されたことが分からなくなる)

java.util.concurrent.ExecutorServiceには

  • isShutdown
  • isTerminated

が含まれており,その戻り値は

isShutdown isTerminated
作業中 false false
終了処理中 true false
終了 true true

ちなみに,interruptメソッドを呼び出すと,スレッドにインタラプトをかけることができるが,この結果は次の

  1. スレッドが「インタラプト状態」になる(状態への反映)
  2. 例外InterruptedExceptionが投げられる(制御への反映)

のいずれかとなる.通常は(1)で,スレッドがsleep, wait, join していた場合には(2)になる.これを変換することを考える.

  1. インタラプト状態→例外InterruptedException
    if (Thread.interrupted()) { // interrupt state of Thread.currentThread()
        throw new InterruptedException();
    }
  2. 例外InterruptedException→インタラプト状態
    try {
        (Long time execution)
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中