『増補改訂版 Java言語で学ぶデザインパターン入門 マルチスレッド編』に載っているデザインパターンを Groovy/GPars で書こうシリーズ、の続き。 今回は Immutable パターン。 状態が変わらないオブジェクトは、いつどのようにスレッドからアクセスされても大丈夫!ってパターン。 状態が変わらないオブジェクトは不変(不可変 immutable)と言いますね。 Immutable なクラスは使うのは簡単ですが、作るのには結構注意がいります・・・ Java では。 Groovy では @Immutable アノテーションを使えば簡単に実装できます。 注意事項がないわけではないですが。 詳しくは「Immutable AST Macro」参照。
参考 URL
- 「Immutable AST Macro」
- Groovy API 「Immutable」
サンプル・コード
作成するソースは
- Immutable な Person クラス
- 実行スクリプト
です。
Person クラス
Immutable なクラスは @Immutable アノテーションを付加するだけで OK:
import groovy.transform.Immutable @Immutable class Person { String name, address }
これで getter メソッドや equals() メソッドなどが自動で生成されます。 setter メソッドは生成されません。 コンストラクタは Map を引数にとるものが自動生成されます*1。
実行スクリプト
これを使用するコードは、正直つまらないですが以下のようになります。
def alice = new Person(name:'Alice', address:'Alaska') 3.times{ // Person を表示し続けるスレッドを作成・開始 Thread.start printPerson(alice) } /** スレッドで実行する処理を書いたクロージャを返す */ def printPerson(Person person){ return { while(true){ println "${Thread.currentThread().name} prints $person" // Person#toString() 使用 } } }
各スレッドは Person クラスの toString() メソッドを呼び出しますが、Person オブジェクトは状態が変わらないので toString() メソッドを synchronized にしたりしなくてもキチンと動作します。
追記
実行スクリプトを Actor で書くとこんな感じでしょうか:
import groovyx.gpars.actor.Actors def alice = new Person(name:'Alice', address:'Alaska') def actors = [] 3.times{ actors << Actors.actor{ loop { println "${Thread.currentThread().name} prints $alice" } } } actors*.join() // 3つの Actor オブジェクトに対して join() メソッドを呼び出す
最後の行は、3つの Actor オブジェクト(リスト actors に格納されている)に対して join() メソッドを呼び出しています。 これを行わないとすぐにスクリプトの実行が終了してしまいます。
増補改訂版 Java言語で学ぶデザインパターン入門 マルチスレッド編
- 作者: 結城浩
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2006/03/21
- メディア: 大型本
- 購入: 15人 クリック: 287回
- この商品を含むブログ (199件) を見る
- 作者: 関谷和愛,上原潤二,須江信洋,中野靖治
- 出版社/メーカー: 技術評論社
- 発売日: 2011/07/06
- メディア: 単行本(ソフトカバー)
- 購入: 6人 クリック: 392回
- この商品を含むブログ (152件) を見る