#Balkingパターン
balkとは、やめて帰ること。野球のボークもbalk。Balkingパターンにも、Guarded Suspensionパターンと同様に、ガード条件が登場する。Balkingパターンでは、ガード条件が満たされなかったら、すぐに中断する。これが、実行できる状態になるまで待つGuarded Suspensionパターンとの違い。
エディタの自動保存機能みたいなものを考える。現在のデータの内容を定期的にファイルに書き込むという処理をするスレッドがいる。データの内容が更新されたときのみセーブする。データの内容に違いがあることをガード条件とし、違いがなかったらファイルに書き込む処理を行わずに帰る(balkする)。
(コード全体は本書を参照のこと)
...
public synchronized void change(String newContent) {
content = newContent;
changed = true;
}
public synchronized void save() throws IOException {
if (!changed) { // 変更されていなければ
return; // balkする
}
doSave();
changed = false;
}
...
##登場人物
GuardedObject役は、ガードされたメソッド(guardedMethod)を持っているクラス。ガード条件が満たされていればすぐに実行し、満たされていなければ実際の処理へは行かずに帰る。GuardedObjec役は、インスタンスの状態を変化させるメソッド(stateChangingMethod)を持つ場合がある。サンプルプログラムではDataクラスがこの役をつとめ、saveメソッドがguardedMethod、changeフィールドがstateChangingMethodに対応する。
##どんなときに使うのか
- あえて処理の必要がない場合
- ガード条件が満たされるのを待ちたくない場合
- ガード条件が満たされるのが最初の1回だけという場合。例えば初期化しているかどうかを調べ、初期化されていない場合に一度だけ初期化する場合。
...
public synchronized void init() {
if (initialized) {
return;
}
doInit();
initialized = true;
}
initializedフィールドのように、「たった一度だけ状態が変化する変数」のことを、一般的にラッチ(latch:掛け金)と呼ぶ。
##タイムアウト
BalkingパターンとGuarded Suspensionパターンの中間として、ガード条件を満たすまで一定時間待つという対処方法がある。ガード条件を満たすまで一定時間まち、それでもまだ条件が満たされなかった場合にはbalkすると言った処理を、guarded timedあるいはtimeoutと呼ぶ。
obj.wait(1000) // 1000ミリ秒待つ
しかし、Javaには、notify/notifyAllされたのかタイムアウトしたのかを区別する方法がない。
関連
『Java言語で学ぶデザインパターン(マルチスレッド編)』まとめ(その1)
『Java言語で学ぶデザインパターン(マルチスレッド編)』まとめ(その2)
『Java言語で学ぶデザインパターン(マルチスレッド編)』まとめ(その3)
『Java言語で学ぶデザインパターン(マルチスレッド編)』まとめ(その4)
『Java言語で学ぶデザインパターン(マルチスレッド編)』まとめ(その5)