モジュール java.base

クラスReentrantReadWriteLock

java.lang.Object
java.util.concurrent.locks.ReentrantReadWriteLock
すべての実装されたインタフェース:
Serializable, ReadWriteLock

public class ReentrantReadWriteLock extends Object implements ReadWriteLock, Serializable
ReentrantLockと同様のセマンティックスをサポートするReadWriteLockの実装です。

このクラスには次の特性があります。

  • 取得順序

    このクラスは、ロック・アクセスに対するリーダーまたはライターの優先順序を規定しません。 ただし、オプションの公平性ポリシーをサポートします。

    不公平モード(デフォルト)
    不公平として構築された場合は(デフォルト)、読み込みおよび書込みロックに入る順序は指定されず、再入可能性制約に従います。 継続的に競合していた不公平ロックでは、1つ以上のリーダーまたはライター・スレッドを無期限に延期することがありますが、通常は公平ロックよりスループットが高くなります。
    公平モード
    公平として構築された場合、スレッドは近似の到着順ポリシーを使用してエントリで競合します。 現在保持されているロックが解放されると、待機時間のもっとも長い単一のライター・スレッドに書込みロックが割り当てられるか、待機中のどのライター・スレッドよりも長く待機しているリーダー・スレッドのグループが存在する場合は、そのグループに読込みロックが割り当てられます。

    書込みロックが保持されている場合や待機中のライター・スレッドが存在する場合、公平読込みロック(再入不可能)を取得しようとするスレッドはブロックされます。 そのようなスレッドは、現在待機中のライター・スレッドのうちもっとも古いスレッドが書込みロックを取得して解放するまで、読込みロックを取得しません。 もちろん、待機中のライターが待機を中止し、キュー内でもっとも長く待機している1つ以上のリーダー・スレッドに書込みロックがかかっていない場合は、それらのリーダーに読込みロックが割り当てられます。

    読込みロックも書込みロックもかかっていない(つまり待機中のスレッドがない)場合を除き、公平書込みロック(再入不可能)を取得しようとするスレッドはブロックされます。 (非ブロックのReentrantReadWriteLock.ReadLock.tryLock()メソッドとReentrantReadWriteLock.WriteLock.tryLock()メソッドはこの公平設定に従わず、待機中のスレッドには関係なく、可能であればロックをただちに取得することに注意してください。)

  • 再入可能性

    このロックにより、リーダーとライターの両方が、ReentrantLockのスタイルで読み取りまたは書込みロックを再取得できるようになります。 書き込むスレッドの保持する書込みロックがすべて解放されるまで、再入不可能なリーダーは許可されません。

    また、ライターは読込みロックを取得できますが、リーダーが書込みロックを取得することはできません。 ほかのアプリケーションの間では、読込みロック下で読込みを実行するメソッドへの呼び出しまたはコールバック中に書込みロックが保持される場合、再入可能性は有用です。 リーダーが書込みロックを取得しようとしても、成功しません。

  • ロックの降格

    再入可能性を利用すると、書込みロックを取得してから読込みロックを取得し、その後書込みロックを解放するという方法で、書込みロックから読込みロックへの降格が可能になります。 ただし、読込みロックから書込みロックへの昇格はできません

  • ロック取得の割り込み

    読込みロックと書込みロックの両方が、ロック取得中の割込みをサポートします。

  • Conditionのサポート

    書込みロックの提供するCondition実装は、書込みロックに関して、ReentrantLock.newCondition()によって提供されるCondition実装がReentrantLockに対して実行するのと同じように動作します。 このConditionは当然、書込みロックでのみ使用できます。

    読込みロックはConditionをサポートしていないため、readLock().newCondition()UnsupportedOperationExceptionをスローします。

  • インストゥルメンテーション

    このクラスは、ロックが保持されるか競合するかを判別するメソッドをサポートします。 これらのメソッドは、同期の制御用としてではなく、システム状態の監視用として設計されています。

このクラスの直列化は、組込みロックと同様に動作します。直列化解除されたロックは、直列化時の状態にかかわらず、ロック解除状態になります。

使用例 次のコード例では、キャッシュを更新したあとにロックの降格を実行する方法を示します(入れ子を使用しない方法で複数のロックを処理する場合の例外処理は特に注意が必要)。

 
 class CachedData {
   Object data;
   boolean cacheValid;
   final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

   void processCachedData() {
     rwl.readLock().lock();
     if (!cacheValid) {
       // Must release read lock before acquiring write lock
       rwl.readLock().unlock();
       rwl.writeLock().lock();
       try {
         // Recheck state because another thread might have
         // acquired write lock and changed state before we did.
         if (!cacheValid) {
           data = ...
           cacheValid = true;
         }
         // Downgrade by acquiring read lock before releasing write lock
         rwl.readLock().lock();
       } finally {
         rwl.writeLock().unlock(); // Unlock write, still hold read
       }
     }

     try {
       use(data);
     } finally {
       rwl.readLock().unlock();
     }
   }
 }
ReentrantReadWriteLocksを使用して、ある種のCollectionsの使用で並行性を改善できます。 通常、これが価値があるのは、コレクションが大規模になることが予想され、ライター・スレッドよりも多数のリーダー・スレッドによりアクセスされ、同期によるオーバーヘッドを上回るオーバーヘッドを持つ操作が含まれる場合です。 例として、大規模で、並行アクセスが予想されるTreeMapを使用するクラスを次に示します。
 
 class RWDictionary {
   private final Map<String, Data> m = new TreeMap<>();
   private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
   private final Lock r = rwl.readLock();
   private final Lock w = rwl.writeLock();

   public Data get(String key) {
     r.lock();
     try { return m.get(key); }
     finally { r.unlock(); }
   }
   public List<String> allKeys() {
     r.lock();
     try { return new ArrayList<>(m.keySet()); }
     finally { r.unlock(); }
   }
   public Data put(String key, Data value) {
     w.lock();
     try { return m.put(key, value); }
     finally { w.unlock(); }
   }
   public void clear() {
     w.lock();
     try { m.clear(); }
     finally { w.unlock(); }
   }
 }

実装上のノート:

このロックは、最大65535の再帰的書込みロックおよび65535の読込みロックをサポートします。 これらの制限を超えようとすると、ロックしているメソッドからErrorがスローされます。

導入されたバージョン:
1.5
関連項目:
直列化された形式
  • ネストされたクラスのサマリー

    ネストされたクラス
    修飾子と型
    クラス
    説明
    static class 
    readLock()メソッドによって返されたロックです。
    static class 
    writeLock()メソッドによって返されたロックです。
  • コンストラクタのサマリー

    コンストラクタ
    コンストラクタ
    説明
    デフォルト(不公平)の順序プロパティで、新規ReentrantReadWriteLockを作成します。
    ReentrantReadWriteLock​(boolean fair)
    指定された公平性ポリシーを使用して、新しいReentrantReadWriteLockを作成します。
  • メソッドのサマリー

    修飾子と型
    メソッド
    説明
    protected Thread
    現在書込みロックを所有しているスレッドを返します。ロックが所有されていない場合はnullを返します。
    protected Collection<Thread>
    読込みロックの取得を待機中のスレッドを含むコレクションを返します。
    protected Collection<Thread>
    読込みロックまたは書込みロックのいずれかの取得を待機中のスレッドを含むコレクションを返します。
    protected Collection<Thread>
    書込みロックの取得を待機中のスレッドを含むコレクションを返します。
    int
    読込みロックまたは書込みロックの取得を待機中のスレッドの推定数を返します。
    int
    現在のスレッドによる、このロック上の再入可能な読込み保持数を照会します。
    int
    このロック用に保持されている読込みロックの数を照会します。
    protected Collection<Thread>
    書込みロックに関連付けられた指定の状態を待機中のスレッドを含むコレクションを返します。
    int
    書込みロックに関連付けられた指定の状態で待機中のスレッドの推定数を返します。
    int
    現在のスレッドによる、このロック上の再入可能な書込み保持数を照会します。
    boolean
    読込みロックまたは書込みロックの取得を待機中の指定のスレッドが存在するかどうかを照会します。
    boolean
    読込みロックまたは書込みロックの取得を待機中のスレッドが存在するかどうかを照会します。
    boolean
    hasWaiters​(Condition condition)
    この書込みロックに関連付けられた指定状態で待機しているスレッドが存在するかどうかを照会します。
    boolean
    このロックで公平性がtrueに設定されている場合はtrueを返します。
    boolean
    書込みロックがスレッドに保持されているかどうかを照会します。
    boolean
    現在のスレッドがこの書込みロックを保持しているどうかを照会します。
    読込みに使用するロックを返します。
    このロックおよびその状態を識別する文字列を返します。
    書込みに使用するロックを返します。

    クラス java.lang.Objectで宣言されたメソッド

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
  • コンストラクタの詳細

    • ReentrantReadWriteLock

      public ReentrantReadWriteLock()
      デフォルト(不公平)の順序プロパティで、新規ReentrantReadWriteLockを作成します。
    • ReentrantReadWriteLock

      public ReentrantReadWriteLock(boolean fair)
      指定された公平性ポリシーを使用して、新しいReentrantReadWriteLockを作成します。
      パラメータ:
      fair - このロックが公平順序付けポリシーを使用する場合はtrue
  • メソッドの詳細

    • writeLock

      インタフェースからコピーされた説明: ReadWriteLock
      書込みに使用するロックを返します。
      定義:
      writeLock、インタフェース: ReadWriteLock
      戻り値:
      書込みに使用するロック
    • readLock

      インタフェースからコピーされた説明: ReadWriteLock
      読込みに使用するロックを返します。
      定義:
      readLock、インタフェース: ReadWriteLock
      戻り値:
      読込みに使用するロック
    • isFair

      public final boolean isFair()
      このロックで公平性がtrueに設定されている場合はtrueを返します。
      戻り値:
      このロックで公平性がtrueに設定されている場合はtrue
    • getOwner

      protected Thread getOwner()
      現在書込みロックを所有しているスレッドを返します。ロックが所有されていない場合はnullを返します。 このメソッドが所有者ではないスレッドによって呼び出される場合、戻り値には現在のロック状態の最大限の近似値が反映されます。 たとえば、ロックの取得を試みていてまだ取得していないスレッドが存在する場合も、所有者は一時的にnullになる場合があります。 このメソッドは、より包括的なロック監視機能を提供するサブクラスの構築を容易にする目的で設計されています。
      戻り値:
      所有者。所有されていない場合はnull
    • getReadLockCount

      public int getReadLockCount()
      このロック用に保持されている読込みロックの数を照会します。 このメソッドは、同期の制御用としてではなく、システム状態の監視用として設計されています。
      戻り値:
      保持する読込みロックの数
    • isWriteLocked

      public boolean isWriteLocked()
      書込みロックがスレッドに保持されているかどうかを照会します。 このメソッドは、同期の制御用としてではなく、システム状態の監視用として設計されています。
      戻り値:
      いずれかのスレッドが書込みロックを保持している場合はtrue。それ以外の場合はfalse
    • isWriteLockedByCurrentThread

      public boolean isWriteLockedByCurrentThread()
      現在のスレッドがこの書込みロックを保持しているどうかを照会します。
      戻り値:
      現在のスレッドが書込みロックを保持している場合はtrue。それ以外の場合はfalse
    • getWriteHoldCount

      public int getWriteHoldCount()
      現在のスレッドによる、このロック上の再入可能な書込み保持数を照会します。 ライター・スレッドは、ロック解除アクションと一致しない各ロック・アクション用のロックを保持します。
      戻り値:
      現在のスレッドの、書込みロックに対する保持数。現在のスレッドがこのロックを保持していない場合はゼロ
    • getReadHoldCount

      public int getReadHoldCount()
      現在のスレッドによる、このロック上の再入可能な読込み保持数を照会します。 読込みスレッドには、ロック解除アクションと一致しないロック・アクションごとに、ロック保持が存在します。
      戻り値:
      現在のスレッドの、読込みロックに対する保持数。現在のスレッドがこのロックを保持していない場合はゼロ
      導入されたバージョン:
      1.6
    • getQueuedWriterThreads

      protected Collection<Thread> getQueuedWriterThreads()
      書込みロックの取得を待機中のスレッドを含むコレクションを返します。 実際のスレッド・セットは、結果の構築中にも動的に変化する可能性があるため、返されるコレクションは最善の努力を払った上での推定に過ぎません。 返されるコレクションの要素には、特定の順序は存在しません。 このメソッドは、より包括的なロック監視機能を提供するサブクラスの構築を容易にする目的で設計されています。
      戻り値:
      スレッドのコレクション
    • getQueuedReaderThreads

      protected Collection<Thread> getQueuedReaderThreads()
      読込みロックの取得を待機中のスレッドを含むコレクションを返します。 実際のスレッド・セットは、結果の構築中にも動的に変化する可能性があるため、返されるコレクションは最善の努力を払った上での推定に過ぎません。 返されるコレクションの要素には、特定の順序は存在しません。 このメソッドは、より包括的なロック監視機能を提供するサブクラスの構築を容易にする目的で設計されています。
      戻り値:
      スレッドのコレクション
    • hasQueuedThreads

      public final boolean hasQueuedThreads()
      読込みロックまたは書込みロックの取得を待機中のスレッドが存在するかどうかを照会します。 取消しはいつでも発生する可能性があるため、trueが返されても、ほかのいずれかのスレッドがロックを取得することは保証されていません。 このメソッドは、主にシステム状態の監視に使用する目的で設計されています。
      戻り値:
      ロックの取得を待機中のほかのスレッドが存在する可能性がある場合はtrue
    • hasQueuedThread

      public final boolean hasQueuedThread(Thread thread)
      読込みロックまたは書込みロックの取得を待機中の指定のスレッドが存在するかどうかを照会します。 取消しはいつでも発生する可能性があるため、trueが返されても、このスレッドがロックを取得することは保証されていません。 このメソッドは、主にシステム状態の監視に使用する目的で設計されています。
      パラメータ:
      thread - スレッド
      戻り値:
      指定されたスレッドがキューに入れられており、このロックを待機中である場合はtrue
      例外:
      NullPointerException - スレッドがnullの場合
    • getQueueLength

      public final int getQueueLength()
      読込みロックまたは書込みロックの取得を待機中のスレッドの推定数を返します。 このメソッドが内部のデータ構造をトラバースしている間にも、スレッド数が動的に変化する場合があるため、この値は推定に過ぎません。 このメソッドは、同期の制御用としてではなく、システム状態の監視用として設計されています。
      戻り値:
      このロックを待機しているスレッドの推定数
    • getQueuedThreads

      protected Collection<Thread> getQueuedThreads()
      読込みロックまたは書込みロックのいずれかの取得を待機中のスレッドを含むコレクションを返します。 実際のスレッド・セットは、結果の構築中にも動的に変化する可能性があるため、返されるコレクションは最善の努力を払った上での推定に過ぎません。 返されるコレクションの要素には、特定の順序は存在しません。 このメソッドは、より包括的な監視機能を提供するサブクラスの構築を容易にする目的で設計されています。
      戻り値:
      スレッドのコレクション
    • hasWaiters

      public boolean hasWaiters(Condition condition)
      この書込みロックに関連付けられた指定状態で待機しているスレッドが存在するかどうかを照会します。 タイム・アウトおよび割込みはいつでも発生する可能性があるため、trueが返されても、将来signalがスレッドを起動させることは保証されていません。 このメソッドは、主にシステム状態の監視に使用する目的で設計されています。
      パラメータ:
      condition - 状態
      戻り値:
      待機中のスレッドが存在する場合はtrue
      例外:
      IllegalMonitorStateException - このロックを保持していない場合
      IllegalArgumentException - 指定された状態がこのロックと関連付けられていない場合
      NullPointerException - 状態がnullの場合
    • getWaitQueueLength

      public int getWaitQueueLength(Condition condition)
      書込みロックに関連付けられた指定の状態で待機中のスレッドの推定数を返します。 タイム・アウトおよび割り込みの発生する可能性はいつでも存在するため、推定数は、実際の待機者数に関する上限を示すに過ぎません。 このメソッドは、同期の制御用としてではなく、システム状態の監視用として設計されています。
      パラメータ:
      condition - 状態
      戻り値:
      待機中のスレッドの推定数
      例外:
      IllegalMonitorStateException - このロックを保持していない場合
      IllegalArgumentException - 指定された状態がこのロックと関連付けられていない場合
      NullPointerException - 状態がnullの場合
    • getWaitingThreads

      protected Collection<Thread> getWaitingThreads(Condition condition)
      書込みロックに関連付けられた指定の状態を待機中のスレッドを含むコレクションを返します。 実際のスレッド・セットは、結果の構築中にも動的に変化する可能性があるため、返されるコレクションは最善の努力を払った上での推定に過ぎません。 返されるコレクションの要素には、特定の順序は存在しません。 このメソッドは、より包括的な状態監視機能を提供するサブクラスの構築を容易にする目的で設計されています。
      パラメータ:
      condition - 状態
      戻り値:
      スレッドのコレクション
      例外:
      IllegalMonitorStateException - このロックを保持していない場合
      IllegalArgumentException - 指定された状態がこのロックと関連付けられていない場合
      NullPointerException - 状態がnullの場合
    • toString

      public String toString()
      このロックおよびその状態を識別する文字列を返します。 状態は括弧で囲まれ、文字列"Write locks ="に続いて再入可能として保持されている書込みロックの数、および文字列"Read locks ="に続いて保持されている読込みロックの数が含まれます。
      オーバーライド:
      toString 、クラス:  Object
      戻り値:
      このロックおよびその状態を識別する文字列