multi thread 7

Thread-Per-Message パターン

メソッド呼び出しとスレッド起動を利用して「非同期のメッセージ送信」を行う.

Client class (タスクを依頼.このタスクの要求を実現しているかどうかを受け取らずに返る)

public class Client {
    public static void main(String[] args) {
        Host host = new Host();
        host.request(message);
    }
}

Host class (新規スレッドを作り起動する)

public class Host {
    private final Helper helper = new Helper();
    public void request(final String message) {
        new Thread() {
            public void run() {
                helper.handle(message);
            }
        }.start();
    }
}

Helper class (Hostによって作られたスレッドで実際にタスクを処理する)

public Helper {
    public void handle(String message) {
        (process message)
    }
}

このパターンの特徴

  • 応答性を上げ,遅延時間を下げる
  • 処理の順序を気にしないときにしか使えない(request順には実行されない)
  • 戻り値が不要なときに使う→戻り値を格納するインスタンスをあらかじめ作る(Futureパターン)

ちなみに,Thread, Runnable, java.util.concurrentに含まれるいくつかのパターンをまとめておくと

  • java.lang.Thread
    • 基本的なスレッドの生成・起動のクラス
  • java.lang.Runnable
    • スレッドが実行する「タスク」を表すIF
    • スレッドの生成と同時に書くパターン
    • new Thread(
          new Runnable() {
              public void run() {
                  helper.handle(message);
              }
          }
      ).start();
    • Runnableのインスタンスを作成しておいてそれをセットしたスレッドを起動するパターン
    • Runnable runnable = new Runnable() {
          public void run() {
              helper.handle(message);
          }
      }
      new Thread(runnable).start();
  • java.util.concurrent.ThreadFactory
    • スレッドの生成を抽象化したIF
    • threadFactory に ThreadFactoryオブジェクトを保持しておき,new Thread(…) の代わりに threadFactory.newThread(…) のように利用
    • public class Host {
          private final Helper helper = new Helper();
          private final ThreadFactory threadFactory;
          public Host(ThreadFactory threadFactory) {
              this.threadFactory = threadFactory;
          }
          public void request(final String message) {
              threadFactory.newThread(
                  new Runnable() {
                      public void run() {
                          helper.handle(message);
                      }
                  }
              ).start();
          }
      }
    • Clientクラスは不要でHostクラスを利用する側でスレッド生成の詳細を制御できる
  • java.util.concurrent.Executor
    • スレッドの実行を抽象化したIF
    • ThreadFactory のThreadではなくRunnable版()
    • (スレッド生成ではなく)タスクの生成において,Clientクラスは不要でHostクラスを利用する側でタスク生成の詳細を制御できる
    • public class Host {
          private final Helper helper = new Helper();
          private final Executor executor;
          public Host(Executor executor) {
              this.executor = executor;
          }
          public void request(final String message) {
              executor.execute(
                  new Runnable() {
                      public void run() {
                          helper.handle(message);
                      }
                  }
              );
          }
      }
  • java.util.concurrent.ExecutorService
    • 再利用されるスレッドの実行を抽象化したIF
    • 背後でスレッドがいつも動作しており,executeメソッドを呼び出せばRunnableオブジェクトを実行してくれる
    • サービスの終了にはshutdownメソッドを利用する→それ以上新しいリクエストは受け付けない
    • public class Client {
          public static void main(String[] args) {
              ExecutorService executorService = Executors.newCachedThreadPool();
              Host host = new Host(
                  executorService
              );
              try {
                  host.request(message);
              } finally {
                  executorService.shutdown();
              }
          }
      }
  • java.util.concurrent.ScheduledExecutorService
    • スケジューリングされたスレッドの実行を抽象化したIF
    • 「要求が来てから約3秒後に実行する」というようにスケジューリングされた処理を実行する
    • scheduleメソッドで,どのRunnableオブジェクトをどれだけ遅延させるかを与える
    • public class Host {
          private final Helper helper = new Helper();
          private final ScheduledExecutorService scheduledExecutorService;
          public Host(ScheduledExecutorService scheduledExecutorService) {
              this.scheduledExecutorService = scheduledExecutorService;
          }
          public void request(final String message) {
              scheduledExecutorService.schedule(
                  new Runnable() {
                      public void run() {
                          helper.handle(message);
                      }
                  },
              3L,
              TimeUnit.SECONDS
              );
          }
      }
    • public class Client {
          public static void main(String[] args) {
              ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(the number of threads even though there is no task);
              Host host = new Host(
                  scheduledExecutorService
              );
              try {
                  host.request(message);
              } finally {
                  scheduledExecutorService.shutdown();
              }
          }
      }
広告

コメントを残す

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

WordPress.com ロゴ

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

Twitter 画像

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

Facebook の写真

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

Google+ フォト

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

%s と連携中