『増補改訂版 Java言語で学ぶデザインパターン入門 マルチスレッド編』に載っているデザインパターンを Groovy/GPars で書こうシリーズ、今回は Balking パターン。 前回見た Guarded Suspension パターンでは、(キューが空になったり空きができたりなどのような)条件が満たされるまで処理のリクエスト側が待たされるのに対して、Balking パターンでは条件が満たされていなければすぐに処理を返します。 ってことで、条件の判定に使うフィールドやメソッドをキチンとスレッド対応にしましょう。
サンプル・コード
サンプルで作成するソースは
- Data クラス
- 実行スクリプト
です。 Balking パターンで重要なのは Data クラスのスレッド対応です。 『増補改訂版 Java言語で学ぶデザインパターン入門 マルチスレッド編』には、他に ChangerThread, SaverThread が作られてますが、このパターンではそんなに重要ではないので、ここでは簡単に Actor として作っています(実行スクリプト参照)。
Data クラス
Data クラスは文字列の内容を持つデータを表し、ファイルへのセーブ機能も持っています。 セーブは save() メソッドにより行われますが、内容が変化されていなければ保存処理は行われません。
class Data { private String content private final File file private boolean changed Data(String filename, String content){ this.file = new File(filename) this.content = content this.changed = true } synchronized void change(String newContent){ this.content = newContent this.changed = true } /** name は保存を実行した Actor 名 */ synchronized void save(String name){ if(this.changed){ println "$name calls save, content = $content" this.file.text = this.content this.changed = false } } }
Date オブジェクトが複数のスレッドからアクセスされる場合、内容が変更されたかどうかのフラグ changed の値を変更する処理は同期化された状態で行う必要があります。 よって change(), save() メソッドは synchronized になっています。
実行スクリプト
では実行スクリプト。 changer はデータの変更と手動でのセーブを行い、saver は自動でのセーブを行います:
import groovyx.gpars.actor.Actors final def data = new Data('data.txt', '(empty)') // 必ずしも final にする必要はないけど // 内容変更と手動セーブをエミュレート def changer = Actors.actor{ def i = 0 def random = new Random() loop{ data.change("No. $i") i++ Thread.sleep random.nextInt(1000) data.save('ChangerActor') } } // 自動セーブをエミュレート def saver = Actors.actor{ loop{ data.save('SaverActor') Thread.sleep 1000 } } [changer, saver]*.join() // Actor オブジェクトは join() しましょう
同じことを延々と実行するのは Actor の loop を使って実装しています。

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

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