『増補改訂版 Java言語で学ぶデザインパターン入門 マルチスレッド編』に載っているデザインパターンを Groovy/GPars で書こうシリーズ、今回は Worker Thread パターン。 Worker Thread パターンも java.util.concurrent パッケージのクラスを使えば実装するのは簡単です。 というか、Executor や ExecutorService を使うと Worker Thread パターンと Thread-Per-Message パターンの違いがあんまりよくわかんないですね。 『増補改訂版 Java言語で学ぶデザインパターン入門 マルチスレッド編』によると、この2つのパターンの違いは、処理を行うスレッドを逐次作成するのか?アプリケーションの起動時に作成しておくのか?という違いだそうなので、これらは ExecutorService のインスタンスとしてどれを使うのか?で切り替えられれば、それ以外のコードは同じになってもおかしくはなさそうですね。
サンプル・コード
ではサンプル・コード。 作成するソースは
- Request クラス リクエストをあらわす。 Runnable を実装
- ClientActor リクエストを作成して送信する
- 実行スクリプト
リクエストを受け取って処理を実行するのは ExecutorService (Executor) クラスに任せます。
Request クラス
リクエストを表すクラス。 Runnable を実装することで処理自体も記述されています:
class Request implements Runnable{ private static final Random RANDOM = new Random() private final String name private final int number Request(String name, int number){ this.name = name this.number = number } @Override void run(){ println "${Thread.currentThread().name} executes $this" Thread.sleep 1000 } @Override String toString(){ return "[ Request from $name No. $number ]" } }
ClientActor クラス
ClientActor は、リクエストを作成して ExecutorService オブジェクトに送信し続けます。 GPars の Actor を用いて実装:
class ClientActor extends DefaultActor{ private static final Random RANDOM = new Random() private final String name private final ExecutorService exeService // Executor で充分だったかな? ClientActor(String name, ExecutorService exeService){ this.name = name this.exeService = exeService } @Override void act(){ int i = 0 loop{ try{ def request = new Request(this.name, i) this.exeService.execute(request) Thread.sleep 1000 }catch(InterruptedException | RejectedExecutionException e){ println "$name : $e" } i++ } } }
実行スクリプト
実行スクリプトで ExecutorService オブジェクトの作成と ClientActor オブジェクトの作成を行っています。 今回もThread-Per-Message パターンの場合と同じく GParsExecutorPool が提供する ExecutorService を使用しています。 全く同じ使い方もアレなので、プールのスレッド数と ThreadFactory を指定するようにしてみました:
import groovyx.gpars.GParsExecutorsPool import java.util.concurrent.Executors // スレッドプールのスレッド数と ThreadFactory を設定 GParsExecutorsPool.withPool(10, Executors.defaultThreadFactory()) { def actors = [] actors << new ClientActor('Alice', it).start() actors << new ClientActor('Bobby', it).start() actors << new ClientActor('Chris', it).start() actors*.join() }

増補改訂版 Java言語で学ぶデザインパターン入門 マルチスレッド編
- 作者: 結城浩
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2006/03/21
- メディア: 大型本
- 購入: 15人 クリック: 287回
- この商品を含むブログ (199件) を見る

- 作者: 関谷和愛,上原潤二,須江信洋,中野靖治
- 出版社/メーカー: 技術評論社
- 発売日: 2011/07/06
- メディア: 単行本(ソフトカバー)
- 購入: 6人 クリック: 392回
- この商品を含むブログ (152件) を見る