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
がスローされます。
コンストラクタと説明 |
---|
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()
|
String |
toString()
このロックおよびその状態を識別する文字列を返します。
|
boolean |
tryLock()
呼出し時に別のスレッドにより保持されていない場合にのみ、ロックを取得します。
|
boolean |
tryLock(long timeout, TimeUnit unit)
指定された待機時間内に別のスレッドがロックを保持せず、現在のスレッドで割り込みが発生していない場合に、ロックを取得します。
|
void |
unlock()
このロックの解放を試みます。
|
public ReentrantLock()
ReentrantLock
のインスタンスを生成します。これは、ReentrantLock(false)
の使用と同等です。public ReentrantLock(boolean fair)
ReentrantLock
のインスタンスを作成します。fair
- このロックが公平順序付けポリシーを使用する場合はtrue
public void lock()
ロックが別のスレッドに保持されていない場合、そのロックを取得してただちに復帰し、ロックの保持カウントを1に設定します。
現在のスレッドがロックをすでに保持している場合、保持カウントの値を1増分して、メソッドをただちに復帰します。
ロックが別のスレッドにより保持されている場合、現在のスレッドがスレッド・スケジューリングに関して無効になり、ロックが取得されるまで待機します。ロックが取得されると、ロック保持カウントが1に設定されます。
public void lockInterruptibly() throws InterruptedException
ロックが別のスレッドに保持されていない場合、そのロックを取得してただちに復帰し、ロックの保持カウントを1に設定します。
現在のスレッドがロックをすでに保持している場合、保持カウントの値を1増分して、メソッドをただちに復帰します。
ロックが別のスレッドにより保持されている場合、現在のスレッドはスレッドのスケジューリングに関して無効になり、次の2つのいずれかが起きるまで待機します。
ロックが現在のスレッドにより取得された場合、ロック保持カウントが1に設定されます。
現在のスレッドで、
InterruptedException
がスローされ、現在のスレッドの割込みステータスがクリアされます。
このメソッドは明示的な割込みポイントであるため、この実装では、通常または再入可能なロック取得への割り込みへの応答に高い優先度が与えられます。
lockInterruptibly
、インタフェース: Lock
InterruptedException
- 現在のスレッドで割込みが発生した場合public boolean tryLock()
別のスレッドがロックを保持していない場合にロックを取得し、値true
でただちに復帰して、ロック保持カウントを1に設定します。このロックが公平順序付けポリシーを使用するように設定されている場合でも、ロックが使用可能であれば、ほかのスレッドが現在ロックを待機しているかどうかには関係なく、tryLock()
の呼出しによってそのロックがただちに取得されます。この「バージ」(barging)動作により公平性が失われるとは言え、これは特定の状況下で有用です。このロックの公平性設定を尊重する場合は、ほぼ等価なtryLock(0, TimeUnit.SECONDS)
を使用します(これも割込みを検出する)。
現在のスレッドがロックをすでに保持している場合、保持カウントの値を1増分して、メソッドはtrue
を返します。
ロックが別のスレッドにより保持されている場合、このメソッドは、値false
でただちに復帰します。
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の場合public void unlock()
現在のスレッドがこのロックのホルダーである場合、保持カウントの値が減らされます。保持カウントがゼロになると、ロックが解放されます。現在のスレッドがこのロックのホルダーではない場合、IllegalMonitorStateException
がスローされます。
unlock
、インタフェース: Lock
IllegalMonitorStateException
- 現在のスレッドがこのロックを保持していない場合public Condition newCondition()
Lock
インスタンスで使用するCondition
インスタンスを返します。
返されるCondition
インスタンスは、Object
監視メソッド(wait
、notify
、およびnotifyAll
)を組込み監視ロックで使用する場合と同じ使用方法をサポートします。
Condition
待機または信号送信メソッドのどちらかが呼び出されたときにこのロックが保持されていない場合は、IllegalMonitorStateException
がスローされます。
InterruptedException
がスローされ、スレッドの割込みステータスがクリアされます。
newCondition
、インタフェース: Lock
public int getHoldCount()
スレッドには、ロック解除アクションと一致しないロック・アクションごとに、ロック保持が存在します。
通常、保持カウント情報はテストおよびデバッグ用にのみ使用されます。たとえば、ロックを保持した状態で特定のコード・セクションに入ってはならない場合、そのことを次のように表します。
class X {
ReentrantLock lock = new ReentrantLock();
// ...
public void m() {
assert lock.getHoldCount() == 0;
lock.lock();
try {
// ... method body
} finally {
lock.unlock();
}
}
}
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
public boolean isLocked()
true
。それ以外の場合はfalse
public final boolean isFair()
true
を返します。true
protected Thread getOwner()
null
を返します。このメソッドが所有者ではないスレッドによって呼び出される場合、戻り値には現在のロック状態の最大限の近似値が反映されます。たとえば、ロックの取得を試みていてまだ取得していないスレッドが存在する場合も、所有者は一時的にnull
になる場合があります。このメソッドは、より包括的なロック監視機能を提供するサブクラスの構築を容易にする目的で設計されています。null
public final boolean hasQueuedThreads()
true
が返されても、ほかのいずれかのスレッドがこのロックを取得することは保証されていません。このメソッドは、主にシステム状態の監視に使用する目的で設計されています。true
public final boolean hasQueuedThread(Thread thread)
true
が返されても、このスレッドがこのロックを取得することは保証されていません。このメソッドは、主にシステム状態の監視に使用する目的で設計されています。thread
- スレッドtrue
NullPointerException
- スレッドがnullの場合public final int getQueueLength()
protected Collection<Thread> getQueuedThreads()
public boolean hasWaiters(Condition condition)
true
が返されても、将来signal
がスレッドを起動させることは保証されていません。このメソッドは、主にシステム状態の監視に使用する目的で設計されています。condition
- 状態true
IllegalMonitorStateException
- このロックを保持していない場合IllegalArgumentException
- 指定された状態がこのロックと関連付けられていない場合NullPointerException
- 状態がnullの場合public int getWaitQueueLength(Condition condition)
condition
- 状態IllegalMonitorStateException
- このロックを保持していない場合IllegalArgumentException
- 指定された状態がこのロックと関連付けられていない場合NullPointerException
- 状態がnullの場合protected Collection<Thread> getWaitingThreads(Condition condition)
condition
- 状態IllegalMonitorStateException
- このロックを保持していない場合IllegalArgumentException
- 指定された状態がこのロックと関連付けられていない場合NullPointerException
- 状態がnullの場合 バグまたは機能を送信
詳細なAPIリファレンスおよび開発者ドキュメントについては、Java SEのドキュメントを参照してください。そのドキュメントには、概念的な概要、用語の定義、回避方法、有効なコード例などの、開発者を対象にしたより詳細な説明が含まれています。
Copyright© 1993, 2014, Oracle and/or its affiliates. All rights reserved.