クラスReentrantLock
- すべての実装されたインタフェース:
Serializable,Lock
synchronizedメソッドおよび文を使用してアクセスする暗黙の監視ロックと同じ基本動作およびセマンティックスを使用し、かつ拡張機能を持つ、再入可能な相互排他Lockです。
ReentrantLockは、最後にロックに成功したが、まだロック解除していないスレッドによって所有されます。 ロックが別のスレッドに所有されていない場合、lockを呼び出すスレッドが復帰してロックの取得に成功します。 現在のスレッドがロックをすでに所有している場合、メソッドはただちに復帰します。 これは、isHeldByCurrentThread()メソッドとgetHoldCount()メソッドを使用してチェックできます。
このクラスのコンストラクタは、オプションの公平性パラメータを受け入れます。 trueに設定されている場合は、競合が存在すると、ロックではもっとも長く待機しているスレッドにアクセスが許可されます。 そうでない場合、このロックが特定のアクセス順を保証することはありません。 多数のスレッドによりアクセスされる公平ロックを使用するプログラムは、デフォルト設定を使用するプログラムよりも低い(より低速な、多くの場合非常に低速な)全体スループットを表示する場合がありますが、ロックを取得する際の変動はより小さくなり、枯渇しないことが保証されます。 ただし、ロックの公平性により、スレッド・スケジューリングの公平性が保証されるわけではありません。 このため、公平ロックを使用する多数のスレッドの1つが複数回連続して取得し、アクティブなほかのスレッドの進捗が見られず、ロックを保持していない状態になることもあります。 また、時間指定のないtryLock()メソッドが公平性の設定に従わないことにも注意してください。 ほかのスレッドが待機中でもロックが有効であればこのメソッドは成功します。
次のように、tryブロックを含むlockへのコールの直後にalways実行し、finallyブロックの最初の文としてunlockをすぐにimmediatelyコールすることをお薦めします:
class X {
private final ReentrantLock lock = new ReentrantLock();
// ...
public void m() {
lock.lock(); // lock() as the last statement before the try block
try {
// ... method body
} finally {
lock.unlock(); // unlock() as the first statement in the finally block
}
}
}
Lockインタフェースの実装に加えて、このクラスはロックの状態を検査するためのpublicメソッドおよびprotectedメソッドをいくつか定義します。 これらのメソッドの一部は、計測と監視だけに役立ちます。
このクラスの直列化は、組込みロックと同様に動作します。直列化解除されたロックは、直列化時の状態にかかわらず、ロック解除状態になります。
このロックは、1つのスレッドで最大2147483647の再帰的ロックをサポートします。 この制限を超えようとすると、ロックしているメソッドからErrorがスローされます。
- 導入されたバージョン:
- 1.5
- 関連項目:
-
コンストラクタのサマリー
コンストラクタコンストラクタ説明ReentrantLockのインスタンスを生成します。ReentrantLock(boolean fair) 指定された公平性ポリシーを使用して、ReentrantLockのインスタンスを作成します。 -
メソッドのサマリー
修飾子と型メソッド説明int現在のスレッドの、このロックに対する保持数を照会します。protected ThreadgetOwner()現在このロックを所有しているスレッドを返します。ロックが所有されていない場合はnullを返します。protected Collection<Thread> このロックの取得を待機しているスレッドを含むコレクションを返します。final intこのロックの取得を待機中のスレッドの推定数を返します。protected Collection<Thread> getWaitingThreads(Condition condition) このロックに関連付けられた指定の状態を待機中のスレッドを含むコレクションを返します。intgetWaitQueueLength(Condition condition) このロックに関連付けられた指定の状態で待機中のスレッドの推定数を返します。final booleanhasQueuedThread(Thread thread) 指定されたスレッドがこのロックの取得を待機中かどうかを照会します。final booleanこのロックの取得を待機中のスレッドが存在するかどうかを照会します。booleanhasWaiters(Condition condition) このロックに関連付けられた指定の状態で待機しているスレッドが存在するかどうかを照会します。final booleanisFair()このロックで公平性がtrueに設定されている場合はtrueを返します。boolean現在のスレッドがこのロックを保持しているかどうかを照会します。booleanisLocked()このロックがいずれかのスレッドにより保持されているかどうかを照会します。voidlock()ロックを取得します。void現在のスレッドに対して割り込みが発生していないかぎり、ロックを取得します。toString()このロックおよびその状態を識別する文字列を返します。booleantryLock()呼出し時に別のスレッドにより保持されていない場合にのみ、ロックを取得します。boolean指定された待機時間内に別のスレッドがロックを保持せず、現在のスレッドで割り込みが発生していない場合に、ロックを取得します。voidunlock()このロックの解放を試みます。
-
コンストラクタの詳細
-
ReentrantLock
public ReentrantLock()ReentrantLockのインスタンスを生成します。 これは、ReentrantLock(false)の使用と同等です。 -
ReentrantLock
public ReentrantLock(boolean fair) 指定された公平性ポリシーを使用して、ReentrantLockのインスタンスを作成します。- パラメータ:
fair- このロックが公平順序付けポリシーを使用する場合はtrue
-
-
メソッドの詳細
-
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
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監視メソッド(wait、notify、およびnotifyAll)を組込み監視ロックで使用する場合と同じ使用方法をサポートします。Condition待機または信号送信メソッドのどちらかが呼び出されたときにこのロックが保持されていない場合は、IllegalMonitorStateExceptionがスローされます。- 状態待機メソッドが呼び出されると、ロックが解放されます。その後、ロックが再取得され、ロック保持カウントがメソッドの呼出し時の状態に復元されてから、メソッドが復帰します。
- 待機中にスレッドで割り込みが発生すると、待機は終了し、
InterruptedExceptionがスローされ、スレッドの割込みステータスがクリアされます。 - 待機中のスレッドは、FIFOの順序で信号が送信される。
- 待機中のメソッドから復帰するスレッドがロックを再取得する順序は、スレッドがロックを最初に取得したときの順序と同じになります。これは、デフォルトでは指定されていないが、公平ロックではもっとも長く待機していたスレッドが優先されます。
- 定義:
newCondition、インタフェースLock- 戻り値:
- Conditionオブジェクト
-
getHoldCount
public int getHoldCount()現在のスレッドの、このロックに対する保持数を照会します。スレッドには、ロック解除アクションと一致しないロック・アクションごとに、ロック保持が存在します。
通常、保持カウント情報はテストおよびデバッグ用にのみ使用されます。 たとえば、ロックを保持した状態で特定のコード・セクションに入ってはならない場合、そのことを次のように表します。
class X { final 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 { final ReentrantLock lock = new ReentrantLock(); // ... public void m() { assert lock.isHeldByCurrentThread(); // ... method body } }再入可能なロックが再入不可能な方法で確実に使用されるようにする場合にも、これを使用できます。たとえば:
class X { final 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
-