モジュール java.base

クラスReentrantLock

  • すべての実装されたインタフェース:
    Serializable, Lock

    public class ReentrantLock
    extends Object
    implements Lock, Serializable
    synchronizedメソッドおよび文を使用してアクセスする暗黙の監視ロックと同じ基本動作およびセマンティックスを使用し、かつ拡張機能を持つ、再入可能な相互排他Lockです。

    ReentrantLockは、最後にロックに成功したが、まだロック解除していないスレッドによって所有されます。 ロックが別のスレッドに所有されていない場合、lockを呼び出すスレッドが復帰してロックの取得に成功します。 現在のスレッドがロックをすでに所有している場合、メソッドはただちに復帰します。 これは、isHeldByCurrentThread()メソッドとgetHoldCount()メソッドを使用してチェックできます。

    このクラスのコンストラクタは、オプションの公平性パラメータを受け入れます。 trueに設定されている場合は、競合が存在すると、ロックではもっとも長く待機しているスレッドにアクセスが許可されます。 そうでない場合、このロックが特定のアクセス順を保証することはありません。 多数のスレッドによりアクセスされる公平ロックを使用するプログラムは、デフォルト設定を使用するプログラムよりも低い(より低速な、多くの場合非常に低速な)全体スループットを表示する場合がありますが、ロックを取得する際の変動はより小さくなり、枯渇しないことが保証されます。 ただし、ロックの公平性により、スレッド・スケジューリングの公平性が保証されるわけではありません。 このため、公平ロックを使用する多数のスレッドの1つが複数回連続して取得し、アクティブなほかのスレッドの進捗が見られず、ロックを保持していない状態になることもあります。 また、時間指定のないtryLock()メソッドが公平性の設定に従わないことにも注意してください。 ほかのスレッドが待機中でもロックが有効であればこのメソッドは成功します。

    常に lockの呼出しの直後にtryブロックを続けることが推奨されています。通常、次のような前/後の構築で実行します。

     
     class X {
       private final ReentrantLock lock = new ReentrantLock();
       // ...
    
       public void m() {
         lock.lock();  // block until condition holds
         try {
           // ... method body
         } finally {
           lock.unlock()
         }
       }
     }

    Lockインタフェースの実装に加えて、このクラスはロックの状態を検査するためのpublicメソッドおよびprotectedメソッドをいくつか定義します。 これらのメソッドの一部は、計測と監視だけに役立ちます。

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

    このロックは、1つのスレッドで最大2147483647の再帰的ロックをサポートします。 この制限を超えようとすると、ロックしているメソッドからErrorがスローされます。

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

      コンストラクタ 
      コンストラクタ 説明
      ReentrantLock()
      ReentrantLockのインスタンスを生成します。
      ReentrantLock​(boolean fair)
      指定された公平性ポリシーを使用して、ReentrantLockのインスタンスを作成します。
    • メソッドのサマリー

      修飾子と型 メソッド 説明
      int getHoldCount()
      現在のスレッドの、このロックに対する保持数を照会します。
      protected Thread getOwner()
      現在このロックを所有しているスレッドを返します。ロックが所有されていない場合はnullを返します。
      protected Collection<Thread> getQueuedThreads()
      このロックの取得を待機しているスレッドを含むコレクションを返します。
      int getQueueLength()
      このロックの取得を待機中のスレッドの推定数を返します。
      protected Collection<Thread> getWaitingThreads​(Condition condition)
      このロックに関連付けられた指定の状態を待機中のスレッドを含むコレクションを返します。
      int getWaitQueueLength​(Condition condition)
      このロックに関連付けられた指定の状態で待機中のスレッドの推定数を返します。
      boolean hasQueuedThread​(Thread thread)
      指定されたスレッドがこのロックの取得を待機中かどうかを照会します。
      boolean hasQueuedThreads()
      このロックの取得を待機中のスレッドが存在するかどうかを照会します。
      boolean hasWaiters​(Condition condition)
      このロックに関連付けられた指定の状態で待機しているスレッドが存在するかどうかを照会します。
      boolean isFair()
      このロックで公平性がtrueに設定されている場合はtrueを返します。
      boolean isHeldByCurrentThread()
      現在のスレッドがこのロックを保持しているかどうかを照会します。
      boolean isLocked()
      このロックがいずれかのスレッドにより保持されているかどうかを照会します。
      void lock()
      ロックを取得します。
      void lockInterruptibly()
      現在のスレッドに対して割り込みが発生していないかぎり、ロックを取得します。
      Condition newCondition()
      このLockインスタンスで使用するConditionインスタンスを返します。
      String toString()
      このロックおよびその状態を識別する文字列を返します。
      boolean tryLock()
      呼出し時に別のスレッドにより保持されていない場合にのみ、ロックを取得します。
      boolean tryLock​(long timeout, TimeUnit unit)
      指定された待機時間内に別のスレッドがロックを保持せず、現在のスレッドで割り込みが発生していない場合に、ロックを取得します。
      void unlock()
      このロックの解放を試みます。
    • コンストラクタの詳細

      • ReentrantLock

        public ReentrantLock()
        ReentrantLockのインスタンスを生成します。 これは、ReentrantLock(false)の使用と同等です。
      • ReentrantLock

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

      • lock

        public void lock()
        ロックを取得します。

        ロックが別のスレッドに保持されていない場合、そのロックを取得してただちに復帰し、ロックの保持カウントを1に設定します。

        現在のスレッドがロックをすでに保持している場合、保持カウントの値を1増分して、メソッドをただちに復帰します。

        ロックが別のスレッドにより保持されている場合、現在のスレッドがスレッド・スケジューリングに関して無効になり、ロックが取得されるまで待機します。ロックが取得されると、ロック保持カウントが1に設定されます。

        定義:
        lock、インタフェース: Lock
      • lockInterruptibly

        public void lockInterruptibly()
                               throws InterruptedException
        現在のスレッドに対して割り込みが発生していないかぎり、ロックを取得します。

        ロックが別のスレッドに保持されていない場合、そのロックを取得してただちに復帰し、ロックの保持カウントを1に設定します。

        現在のスレッドがロックをすでに保持している場合、保持カウントの値を1増分して、メソッドをただちに復帰します。

        ロックが別のスレッドにより保持されている場合、現在のスレッドはスレッドのスケジューリングに関して無効になり、次の2つのいずれかが起きるまで待機します。

        • 現在のスレッドによりロックが取得される。
        • ほかのスレッドが現在のスレッドに割り込みを行う。

        ロックが現在のスレッドにより取得された場合、ロック保持カウントが1に設定されます。

        現在のスレッドで、

        • このメソッドへのエントリ上で設定された割込みステータスが保持されるか、
        • ロックの取得中に割り込みが発生した場合、
        InterruptedExceptionがスローされ、現在のスレッドの割込みステータスがクリアされます。

        このメソッドは明示的な割込みポイントであるため、この実装では、通常または再入可能なロック取得への割り込みへの応答に高い優先度が与えられます。

        定義:
        lockInterruptibly、インタフェース: Lock
        例外:
        InterruptedException - 現在のスレッドで割込みが発生した場合
      • tryLock

        public boolean tryLock()
        呼出し時に別のスレッドにより保持されていない場合にのみ、ロックを取得します。

        別のスレッドがロックを保持していない場合にロックを取得し、値trueでただちに復帰して、ロック保持カウントを1に設定します。 このロックが公平順序付けポリシーを使用するように設定されている場合でも、ロックが使用可能であれば、ほかのスレッドが現在ロックを待機しているかどうかには関係なく、tryLock()の呼出しによってそのロックがただちに取得されます このバージ(barging)動作により公平性が失われるとは言え、これは特定の状況下で有用です。 このロックの公平性設定を尊重する場合は、ほぼ等価なtryLock(0, TimeUnit.SECONDS)を使用します(これも割込みを検出する)。

        現在のスレッドがロックをすでに保持している場合、保持カウントの値を1増分して、メソッドはtrueを返します。

        ロックが別のスレッドにより保持されている場合、このメソッドは、値falseでただちに復帰します。

        定義:
        tryLock、インタフェース: Lock
        戻り値:
        ロックされていない状態で、現在のスレッドによりロックが取得されたか、またはロックがすでに現在のスレッドによって保持されていた場合はtrue。それ以外の場合はfalse
      • tryLock

        public boolean tryLock​(long timeout,
                               TimeUnit unit)
                        throws InterruptedException
        指定された待機時間内に別のスレッドがロックを保持せず、現在のスレッドで割り込みが発生していない場合に、ロックを取得します。

        別のスレッドがロックを保持していない場合にロックを取得し、値trueでただちに復帰して、ロック保持カウントを1に設定します。 このロックが公平順序付けポリシーを使用するように設定されていても、ほかのスレッドがロックを待機している場合は、使用可能なロックは取得されません これは、tryLock()メソッドとは対照的です。 公平ロックに対するバージを許可しない、時間設定されたtryLockを使用する場合は、時間設定と非時間設定の両形式を組み合わせて使用します。

         
         if (lock.tryLock() ||
             lock.tryLock(timeout, unit)) {
           ...
         }

        現在のスレッドがロックをすでに保持している場合、保持カウントの値を1増分して、メソッドはtrueを返します。

        ロックが別のスレッドにより保持されている場合、現在のスレッドはスレッドのスケジューリングに関して無効になり、次の3つのいずれかが起きるまで待機します。

        • 現在のスレッドによりロックが取得される。
        • ほかのスレッドが現在のスレッドに割り込みを行う。または
        • 指定された待機時間が経過する。

        ロックが取得された場合は値trueが返され、ロック保持カウントが1に設定されます。

        現在のスレッドで、

        • このメソッドへのエントリ上で設定された割込みステータスが保持されるか、
        • ロックの取得中に割り込みが発生した場合、
        InterruptedExceptionがスローされ、現在のスレッドの割込みステータスがクリアされます。

        指定された待機時間が経過すると、値falseが返されます。 時間がゼロまたはそれより小さい場合、メソッドは待機しません。

        このメソッドは明示的な割込みポイントであるため、この実装では、通常または再入可能なロック取得、および待機時間経過レポートへの割り込みに対する応答に高い優先度が与えられます。

        定義:
        tryLock、インタフェース: Lock
        パラメータ:
        timeout - ロックを待機する時間
        unit - timeout引数の時間単位
        戻り値:
        ロックされていない状態で、現在のスレッドによりロックが取得されたか、またはロックがすでに現在のスレッドによって保持されていた場合はtrue。ロックを取得する前に待機時間が経過した場合はfalse
        例外:
        InterruptedException - 現在のスレッドで割込みが発生した場合
        NullPointerException - 時間単位がnullの場合
      • unlock

        public void unlock()
        このロックの解放を試みます。

        現在のスレッドがこのロックのホルダーである場合、保持カウントの値が減らされます。 保持カウントがゼロになると、ロックが解放されます。 現在のスレッドがこのロックのホルダーではない場合、IllegalMonitorStateExceptionがスローされます。

        定義:
        unlock、インタフェース: Lock
        例外:
        IllegalMonitorStateException - 現在のスレッドがこのロックを保持していない場合
      • newCondition

        public Condition newCondition()
        このLockインスタンスで使用するConditionインスタンスを返します。

        返されるConditionインスタンスは、Object監視メソッド(waitnotify、およびnotifyAll)を組込み監視ロックで使用する場合と同じ使用方法をサポートします。

        • Condition 待機または信号送信メソッドのどちらかが呼び出されたときにこのロックが保持されていない場合は、IllegalMonitorStateExceptionがスローされます。
        • 状態待機メソッドが呼び出されると、ロックが解放されます。その後、ロックが再取得され、ロック保持カウントがメソッドの呼出し時の状態に復元されてから、メソッドが復帰します。
        • 待機中にスレッドで割り込みが発生すると、待機は終了し、InterruptedExceptionがスローされ、スレッドの割込みステータスがクリアされます。
        • 待機中のスレッドは、FIFOの順序で信号が送信される。
        • 待機中のメソッドから復帰するスレッドがロックを再取得する順序は、スレッドがロックを最初に取得したときの順序と同じになります。これは、デフォルトでは指定されていないが、公平ロックではもっとも長く待機していたスレッドが優先されます。

        定義:
        newCondition、インタフェース: Lock
        戻り値:
        Conditionオブジェクト
      • getHoldCount

        public int getHoldCount()
        現在のスレッドの、このロックに対する保持数を照会します。

        スレッドには、ロック解除アクションと一致しないロック・アクションごとに、ロック保持が存在します。

        通常、保持カウント情報はテストおよびデバッグ用にのみ使用されます。 たとえば、ロックを保持した状態で特定のコード・セクションに入ってはならない場合、そのことを次のように表します。

         
         class X {
           ReentrantLock lock = new ReentrantLock();
           // ...
           public void m() {
             assert lock.getHoldCount() == 0;
             lock.lock();
             try {
               // ... method body
             } finally {
               lock.unlock();
             }
           }
         }

        戻り値:
        現在のスレッドの、このロックに対する保持数。現在のスレッドがこのロックを保持していない場合はゼロ
      • isHeldByCurrentThread

        public boolean isHeldByCurrentThread()
        現在のスレッドがこのロックを保持しているかどうかを照会します。

        組込みの監視ロック用のThread.holdsLock(Object)メソッドと同様に、このメソッドは通常、デバッグおよびテストに使用されます。 たとえば、ロックが保持されている場合にのみ呼び出す必要のあるメソッドは、そのことを次のように示すことができます。

         
         class X {
           ReentrantLock lock = new ReentrantLock();
           // ...
        
           public void m() {
               assert lock.isHeldByCurrentThread();
               // ... method body
           }
         }

        再入可能なロックが再入不可能な方法で確実に使用されるようにする場合にも、これを使用できます。次に例を示します。

         
         class X {
           ReentrantLock lock = new ReentrantLock();
           // ...
        
           public void m() {
               assert !lock.isHeldByCurrentThread();
               lock.lock();
               try {
                   // ... method body
               } finally {
                   lock.unlock();
               }
           }
         }

        戻り値:
        現在のスレッドがこのロックを保持している場合はtrue。それ以外の場合はfalse
      • isLocked

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

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

        protected Thread getOwner()
        現在このロックを所有しているスレッドを返します。ロックが所有されていない場合はnullを返します。 このメソッドが所有者ではないスレッドによって呼び出される場合、戻り値には現在のロック状態の最大限の近似値が反映されます。 たとえば、ロックの取得を試みていてまだ取得していないスレッドが存在する場合も、所有者は一時的にnullになる場合があります。 このメソッドは、より包括的なロック監視機能を提供するサブクラスの構築を容易にする目的で設計されています。
        戻り値:
        所有者。所有されていない場合はnull
      • 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()
        このロックおよびその状態を識別する文字列を返します。 状態は括弧で囲まれ、文字列"Unlocked"または文字列"Locked by"に続いて、所有しているスレッドの名前が含まれます。
        オーバーライド:
        toString 、クラス:  Object
        戻り値:
        このロックおよびその状態を識別する文字列