スレッド間の排他・同期制御を目的とするクラス
スレッド間の排他・同期制御を目的とするクラス.このクラスは排他制御または同期制御を必要とする場合の基本的な機能を提供する.
基本的なメカニズムは java と同様, モニタと条件変数によるものである. このクラスを継承したクラスは java.lang.Object と同様に synchronized ブロックを持つことができ, wait / notify によるスレッド間の同期が 可能となる. java ではすべてのオブジェクトがこの 性質を持つが, このライブラリでは TJSyncObject として独立させて継承などに よりこの性質を付加(mix-in)する方針をとる.
基本的には,このクラスは virtual 継承して使用する.そうすれば, 同期のセマンティクスは java.lang.Object のサブクラスと同様になる.
* 【例】 class Xxx : virtual public TJSyncObject { ... } *意味の異なる複数のロックが1オブジェクト内で必要な場合には, このクラスのオブジェクトをインスタンス変数として包含する使い方も可能である. ただし,あるオブジェクトの中に複数の TJSyncObject が含まれる場合, 誤ったロックを獲得して意図しない排他制御となる可能性があるため,注意が 必要である.
TJSyncObject は次のような機能を持っている.
* ◆このクラスのサブクラスのメソッドの先頭で lock() を呼び出すことにより * そのメソッドはモニタオペレーションとなる. * ここでモニタオペレーションとは java の synchronized メソッドと考えて * よい. どのメソッドをモニタオペレーションとするかは java と同様プログ * ラマの選択にまかされる. * * ◆スレッドはモニタオペレーション実行中はそのオブジェクトに対する排他的 * なアクセスが保証される. * * ◆モニタオペレーションの中で wait() を実行すると排他的アクセス権を失っ * てブロックし他のスレッドによる notify() 呼出しまで待たされる. * * ◆他のスレッドによる notify() 呼出しによって制御を得た時は再び排他的ア * クセス権が獲得されている. * * モニタオペレーションのための排他ロックは同一スレッドならばネストすること * が可能である. wait() ではネストされたロックを解放し notify() ではネスト * レベルを含めてロック状態を復元する. * したがってモニタオペレーションの中で別のモニタオペレーションを呼び出しも * 可能である.この仕様は,java.lang.Object と同様である. * * ただし,このクラスの protected メソッド(lock(), unlock(), ...) * は直接呼び出さず TJMonitor クラスと synchronized マクロを経由して * 使うことを推奨する. * TJMonitor クラスと synchronized マクロは, より安全性と * ドキュメント性を高めている.(TJMonitor を参照) * * java.lang.Object の仕様を参考にしているため次のような使い方を想定している. * * java TJSyncObject * ----------------------------------------------------------- * synchronized void method() { void method() { * lock(); * ・・・ ・・・ * unlock(); * } } * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * synchronized void method() { void method() { * lock(); * ・・・ ・・・ * while (busy) while (busy) * wait(); // catch 省略 wait(); * // object を操作 // object を操作 * ・・・ ・・・ * unlock(); * } } * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * synchronized void method() { void method() { * lock(); * ・・・ ・・・ * notify(); notify(); * ・・・ ・・・ * unlock(); * } } * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * synchronized (obj) { obj.lock(); * ・・・ ・・・ * } obj.unlock(); * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * synchronized (obj) { obj.lock(); * ・・・ ・・・ * while (obj.busy) while (obj.busy) * obj.wait(); // catch 省略 obj.wait(); * // obj を操作 // obj を操作 * ・・・ ・・・ * } obj.unlock(); * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * synchronized (obj) { obj.lock(); * ・・・ ・・・ * obj.notify(); obj.notify(); * ・・・ ・・・ * } obj.unlock(); * ----------------------------------------------------------- *上記を synchronized ブロック記法によってサポートする例は, TJMonitor を参照のこと.
また,unlockTemporarily(), restoreLock() は java には存在しない機能 である.これは,synchronized ブロック中に,ロックを外すことができる 機能である.java では,synchronized ブロックを書くことで synchronized 中であることは保証できるが,逆に呼び出しのネスト関係によりコードの ある部分が synchronized 外あることは保証できない.
この機能により,デッドロックの回避のためのロックの順序化(階層化)を 論理的にサポートすることができる.
引数のオブジェクトを無視して新規作成する.
代入に対してこのオブジェクトを変化させない.
サブクラスでは,このメソッドを継承して自己一貫性チェックを
書くことを推奨する.
開発時に assert() の引数として利用できる.
TJSyncObject(const TJSyncObject& obj)
TJSyncObject& operator=(const TJSyncObject& obj)
virtual ~TJSyncObject()
void wait()
bool wait(long milliseconds)
void notify()
void notifyAll()
virtual bool invariant() const
void lock()
void unlock()
int unlockTemporarily()
void restoreLock(int lockcount)
索引(アルファベット順) HTMLクラス継承 または Java