Skip to content.

Sections
Personal tools
You are here: Home » ダウンロード » ThreadJack用 » doc » TJMonitor

Document Actions

class TJMonitor

モニタオペレーションを支援するためのクラス

Public クラス

[more]enumMode
オブジェクト作成時にロックを獲得するか解放するか

Public メソッド

[more]explicit TJMonitor(const TJSyncObject* obj, Mode mode = LOCK)
TJMonitor オブジェクトを作成する
[more]virtual ~TJMonitor()
TJMonitor オブジェクトを消去する
[more]operator bool() const
synchronized マクロをサポートるための変換

文書

モニタオペレーションを支援するためのクラス.

モニタとは内部に共有データを持ち, その操作メソッドが必ず排他的なアクセス となるように保証された抽象データ型である. そしてモニタオペレーションとは 排他的アクセスの保証されたメソッドを意味するものとする. Java の synchronized method は Object をモニタとするモニタオペレーション の例である.

このクラスはできるだけ安全にモニタオペレーションを実現することを目的とし ている. また,java の synchronized block 記法もマクロにより提供する. コンストラクタとデストラクタによってロックの取得と解放を実現している ため,途中の return や例外による return に対してもロックの解放を 保証できる.

TJMonitor は TJSyncObject を使いやすくしたクラスであり実質的な 機能は TJSyncObject に負っている. TJSyncObject のドキュメント を参照のこと.

基本的な使用法は以下の通り.

synchronized マクロを使用する例

 *  class Xxx : virtual public TJSyncObject {
 *    // ....
 *       void method() {
 *          // ...
 *          synchronized(this) { // ここでロックを取得
 *              // 排他的な操作が保証される
 *          } // ここでロックを解放
 *          // ...
 *
 *       }
 *  };
 * 

TJMonitor をそのまま使用する例(上記と同じ意味)

 *  class Xxx : virtual public TJSyncObject {
 *    // ....
 *       void method() {
 *          // ...
 *          {  TJMonitor sync(this);  // ここでロックを取得
 *             // 排他的な操作が保証される
 *          }  // ここでロックを解放
 *          // ...
 *
 *       }
 *  };
 * 

TJSyncObject の protected メソッドを直接使用する例

 *  class Xxx : virtual public TJSyncObject {
 *    // ....
 *       void method() {
 *          // ...
 *          lock(); // ここでロックを取得
 *          // 排他的な操作が保証される
 *          unlock(); // ここでロックを解放
 *          // ...
 *
 *       }
 *  };
 * 

また,TJSyncObject では java にない機能として,一時的にロックを完全に外す 機能がある.これは,unlock(),~JTMonitor(), および synchronized ブロックの 終わりが,必ずしもロックの解放を保証できないことからサポートされた 機能である.他の synchronized ブロックの中からら呼ばれた別のメソッド内 に於いては,ロックの取得情報がコンテキスト依存となることになるからである.

この機能は,以下のように利用できる.

unsynchronized マクロを使用する例

 *  class Xxx : virtual public TJSyncObject {
 *    // ....
 *       void method() {
 *          synchronized(this) { // ここではロックを取得
 *              // 排他的な操作が保証される.
 *              unsynchronized(this) {  // 一時的にロックを解放
 *                 // ここはロックが外れていることが保証される
 *              }
 *              // 再びロックが復元される(しかし前の状況とは違う可能性あり)
 *          }
 *
 *       }
 *  };
 * 

TJMonitor をそのまま使用する例(上記と同じ意味)

 *  class Xxx : virtual public TJSyncObject {
 *    // ....
 *       void method() {
 *          { TJMonitor sync(this) // ここでロックを取得
 *              // 排他的な操作が保証される.
 *              { TJMonitor unsync(this, TJMonitor::UNLOCK); // 一時的にロックを解放
 *                 // ここはロックが外れていることが保証される
 *              }
 *              // 再びロックが復元される(しかし前の状況とは違う可能性あり)
 *          }
 *       }
 *  };
 * 

TJSyncObject の protected メソッドを直接使用する例

 *  class Xxx : virtual public TJSyncObject {
 *    // ....
 *       void method() {
 *          lock();  // ここではロックを取得
 *          // 排他的な操作が保証される.
 *          int lock = unlockTemporarily(); // 一時的にロックを解放
 *          // ここはロックが外れていることが保証される
 *          restoreLock(lock);
 *          // ... 再びロックが復元される(しかし前の状況とは違う可能性あり)
 *          unlock();
 *       }
 *  };
 * 

この機能は,wait 以外にもロックを完全に解放して要求を待つような 仕組みを提供すること,また,デッドロックの回避のためのロックの順序化 (階層化)を論理的にサポートすることを目的としている.(TJSyncObject 参照)

このクラスのオブジェクトを作成する時にはモードを指定できる. デフォルトの LOCK モードでは通常の排他ロックを獲得するが UNLOCK モードで は逆に獲得されているロックを解放する.

この逆操作が必要になる理由は, モニタの内部で TJSyncObject::wait() 以外で ロックを解放して何らかのイベントを待ち合わせしたい場合があるためである. たとえば TJQueue や外部からの入力などが該当する. それに対して TJSyncObject::wait()は自動的にロックを解放して notify() を 待ち復帰時にはロック取得状態で戻るため, ロック解放の繁雑さを避けることが できる. 次の例を参照.

java と TJMonitor との表現の違いをまとめると次のようになる. ただし synchronized マクロを使うと synchronized block はまったく同じ 表現が可能だが synchronized method は残念ながらメソッド本体を synchronized block の形式にするしかない.

 *
 *          java                               TJMonitor
 *   -------------------------------------------------------------------
 *   synchronized void method() {       void method() {
 *         ・・・                           TJMonitor monitor(syncptr);
 *   }                                        ・・・
 *                                      }
 *                                           または
 *                                      void method() {
 *                                          synchronized(syncptr) {
 *                                              ・・・
 *                                          }
 *                                      }
 *   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 *   synchronized(obj) {                {
 *         ・・・                           TJMonitor syncblock(obj);
 *   }                                        ・・・
 *                                      }
 *                                           または
 *                                      synchronized(obj) {
 *                                            ・・・
 *                                      }
 *   -------------------------------------------------------------------
 * 

[デッドロックに関する注意]

次の操作はデッドロックを起こさない.

 *     ◆モニタオペレーションの再帰呼出し
 *     ◆モニタオペレーションの中から同一オブジェクトの別のモニタオペレー
 *       ションを呼出すこと
 * 

しかし次の操作はタイミングによってはデッドロックとなる.

 *     ◆オブジェクト A,B があり A.m1(), B.m2() がモニタオペレーションと
 *       して A.m1() から B.m2() を呼出し B.m2() から A.m1() を呼出す場合
 * 

同時に複数のロックが必要な場合の解決案を示しておく. たとえば上記のデッドロックのケースならば A,B を TJSyncObject のサブクラスとする. ロックを獲得する順序を決める. A.lock(); B.lock(); ・・・ B.unlock(); A.unlock();

enum Mode
オブジェクト作成時にロックを獲得するか解放するか.

LOCK: ロックを獲得, UNLOCK: ロックを解放

explicit TJMonitor(const TJSyncObject* obj, Mode mode = LOCK)
TJMonitor オブジェクトを作成する.

パラメータ:
obj - ロック用オブジェクトのポインタ
mode - LOCK: ロックを獲得, UNLOCK: ロックを解放

virtual ~TJMonitor()
TJMonitor オブジェクトを消去する.

LOCKモードのオブジェクトはロックを解放し, UNLOCKモードの オブジェクトはロックを復元する.

operator bool() const
synchronized マクロをサポートるための変換.

返す値 :
常に false


子クラスは存在しません
作者 :
Susumu TOKUI @date 1998,6/1
参照 :
TJSyncObject

索引(アルファベット順) HTMLクラス継承 または Java



This page was generated with the help of DOC++.