yohhoyの日記

技術的メモをしていきたい日記

モニタ同期・待機処理と再帰ロックサポート

プログラミング言語Javaが提供するモニタ同期(synchronized構文)および待機処理(Object#wait)は、再帰ロックのセマンティクスをサポートする。*1

メモ:待機処理でも再帰ロックをサポートする仕様は珍しい?C++標準ライブラリ(→id:yohhoy:20120802)やPOSIX標準ライブラリ(Pthreads)*2では、再帰ミューテックスと条件変数待機の組み合わせは正常動作しない。

class SharedValue {
  private final Object monitor = new Object();
  private int value = 0;

  public void updateValue() {
    synchronized (monitor) {    // OK: 1回目のモニタロック獲得
      //...
      synchronized (monitor) {  // OK: 2回目のモニタロック獲得
        value += 1;
        monitor.notifyAll();
      } // モニタロック解放(2→1)
      value += 2;
      monitor.notifyAll();
    } // モニタロック解放(1→0)
  }

  public void awaitValue() throws InterruptedException {
    synchronized (monitor) {
      //...
      synchronized (monitor) {
        while (value < 3) {
          // モニタロックを2回保持した状態でObject#waitを呼び出すと、
          // 全てのモニタロックを解放(2→0)してスレッド待機状態になる。
          monitor.wait();
          // Object#waitメソッド呼び出しから制御が戻ってきたとき、
          // モニタロックを2回保持した状態(0→2)で処理継続する
        }
      } // モニタロック解放(2→1)
      //...
    } // モニタロック解放(1→0)
  }
}

Java Language Specification, Java SE 8 Editionより一部引用(下線部は強調)。

The Java programming language provides multiple mechanisms for communicating between threads. The most basic of these methods is synchronization, which is implemented using monitors. Each object in Java is associated with a monitor, which a thread can lock or unlock. Only one thread at a time may hold a lock on a monitor. Any other threads attempting to lock that monitor are blocked until they can obtain a lock on that monitor. A thread t may lock a particular monitor multiple times; each unlock reverses the effect of one lock operation.

Chapter 17. Threads and Locks, 17.1. Synchronization

Let thread t be the thread executing the wait method on object m, and let n be the number of lock actions by t on m that have not been matched by unlock actions. One of the following actions occurs:

  • If n is zero (i.e., thread t does not already possess the lock for target m), then an IllegalMonitorStateException is thrown.
  • (snip)
  • Otherwise, the following sequence occurs:
    1. Thread t is added to the wait set of object m, and performs n unlock actions on m.
    2. (snip)
    3. Thread t performs n lock actions on m.
    4. (snip)
Chapter 17. Threads and Locks, 17.2.1. Wait

関連URL

*1:Java標準ライブラリ提供の java.util.concurrent.locks.ReentrantLock クラスと同じセマンティクス。ReentrantLock クラスから生成された Condition オブジェクトも、待機処理(Condition#await)で再帰ロックをサポートする。

*2:http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_gettype.html