multi thread 11, 12

§11. Thread-Specific Storage パターン

シングルスレッドの環境で動作することを想定しているオブジェクトをマルチスレッドで利用したいとする.この場合,スレッド固有の記憶領域を確保することになる.もともとスレッドはメソッドの局所変数を保持しているスタックとして,固有の領域を持っている.その局所変数はそのスレッド固有のものであり,他のスレッドからアクセスされることはないが,メソッド呼び出しが終了すれば消えてしまう.

そこで,java.lang.ThreadLocalに格納していく.このインスタンスはコレクションの一種で,メソッド呼び出しとは無関係にスレッド固有の領域を確保するためのクラス.

つまりスレッド固有の情報を置く場所は次の二つがある

  • スレッド外(thread-external)
    ThreadLocalのインスタンスに格納する場合.スレッドを表す既存のクラスを修正する必要がなく,任意のスレッドに適用可能.その代わり,スレッドを表すクラスのソースが理解しにくくなる危険性がある.
  • スレッド内(thread-internal)
    Threadクラスのサブクラス内でフィールド宣言をすればスレッド固有の情報になる.スレッドのソースを読めばスレッド固有の情報が何か分かりやすくなる.その代わり,後からスレッド固有の情報を追加するときはこのサブクラスを書き換える必要がある.

ちなみに,スレッドとスレッドが利用する情報の関係について,アクター・ベースとタスク・ベースという考えがある.

  • アクター・ベース
    「スレッド」が主体.スレッドを表すインスタンスに対して,仕事を行うための情報を持たせるもの.そうするとスレッド同士がやり取りする情報を小さく・軽くすることができる.
    各スレッドは他のスレッドから受け取った情報を使って処理を行い,自分の内部情報を変化せる.

    class Actor extends Thread {
        (The actor's internal state)
        public void run() {
            (Recieving the external task from another thread, the actor's internal state is changed.)
        }
    }
  • タスク・ベース
    「タスク」が主体.スレッドに情報を持たせないもの.スレッドではなく,スレッド同士がやり取りするインスタンス(「タスク」)の方に情報を持たせる.データを持たせるだけではなく,実行するためのメソッドまで持たせる.なので,実行するのはどのスレッドでも構わない.

    class Task implements Runnable {
        (Information to run the task)
        public void run() {
            (The concrete execution)
        }
    }

§12. Active Object パターン

処理を要求するスレッド(Client)と,処理の内容を記述したオブジェクト(Servant)がいるとする.Servantはシングルスレッドでの利用を想定する.

こんな状況を考える.複数のClientからServantを利用したいけれど,Servantはスレッドセーフではない.Servantの処理に時間がかかる場合でもClientへの応答性を落としたくない.処理の要求順序と実行順序は一致しない.処理の結果はClientへ返す.

これを解決するには

  1. 非同期メッセージを受け取り,Clientとは独立のスレッドを持つ能動的なオブジェクトを構築する.
  2. Schedulerスレッドを1個導入する.
  3. Servantの呼び出しはSchedulerだけが行う.(Servantをマルチスレッド対応せずに複数のClientが処理できる.Worker Threadパターン,Wrapperとも)
  4. Clientからの要求はProxyへのメソッド呼び出しとする.
  5. Proxyはその要求を1つのオブジェクトに変換し,Producer-ConsumerパターンでSchedulerへ渡す(Clientへの応答性を保つ)
  6. Schedulerが実行すべき要求を選び出して実行する.(実行順序はSchedulerが決定)
  7. 実行結果はFutureとしてClientへ返す.
広告

コメントを残す

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

WordPress.com ロゴ

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

Twitter 画像

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

Facebook の写真

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

Google+ フォト

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

%s と連携中