public class LockSupport extends Object
このクラスは、それを使用している各スレッドにパーミットを(Semaphore
クラスという意味で)関連付けます。パーミットが使用可能な場合、park
の呼出しはただちに復帰し、プロセス内でそのパーミットを消費します。それ以外の場合は、ブロックされる可能性があります。unpark
の呼出しによって、パーミットがまだ使用可能でなかった場合は使用可能になります。(ただし、Semaphoreとは異なり、パーミットでは累積は実行されません。最大で1つしか存在しません。)
park
メソッドとunpark
メソッドは、非推奨メソッドThread.suspend
およびThread.resume
をこのような目的に使用できなくなるような問題が発生しないスレッドをブロックおよびブロック解除するための効率的な手段を提供します。park
を呼び出しているあるスレッドと、そのスレッドのunpark
を試みている別のスレッドの間の競合は、パーミットのために活発な状態を保持します。さらに、呼出し側のスレッドで割込みが発生し、かつタイムアウト・バージョンがサポートされている場合は、park
が復帰します。park
メソッドはまた「理由なしで」いつでも復帰する可能性があるため、一般には、復帰時に状態を再チェックするループ内で呼び出す必要があります。この意味で、park
はスピンにそれほどの時間を浪費しない「ビジー待機」の最適化として機能しますが、効果を発揮させるにはunpark
とペアにする必要があります。
park
の3つの形式でも、それぞれblocker
オブジェクト・パラメータをサポートします。スレッドがブロックされるとこのオブジェクトが記録されるため、監視および診断ツールでスレッドがブロックされた理由を特定することができます。(このようなツールは、getBlocker(Thread)
メソッドを使用してブロッカにアクセスできます。)このパラメータを指定しない元の形式ではなくこれらの形式を使用することを強くお薦めします。ロック実装内のblocker
として指定する通常の引数はthis
です。
これらのメソッドは、高度な同期ユーティリティの作成用ツールとして使用するように設計されており、それ自体では、たいていの同時制御アプリケーションでは有用ではありません。park
メソッドは、次の形式の構築でのみ使用するように設計されています。
while (!canProceed()) { ... LockSupport.park(this); }
ここで、canProceed
も、park
の呼出しの前のその他のいずれのアクションも、ロックやブロックを伴いません。各スレッドに関連付けられたパーミットは1つだけであるため、park
を中間的に使用すると、その意図された効果を妨げる可能性があります。
使用例。次に、先入れ先出しの再入不可能なロック・クラスの概略を示します。
class FIFOMutex {
private final AtomicBoolean locked = new AtomicBoolean(false);
private final Queue<Thread> waiters
= new ConcurrentLinkedQueue<Thread>();
public void lock() {
boolean wasInterrupted = false;
Thread current = Thread.currentThread();
waiters.add(current);
// Block while not first in queue or cannot acquire lock
while (waiters.peek() != current ||
!locked.compareAndSet(false, true)) {
LockSupport.park(this);
if (Thread.interrupted()) // ignore interrupts while waiting
wasInterrupted = true;
}
waiters.remove();
if (wasInterrupted) // reassert interrupt status on exit
current.interrupt();
}
public void unlock() {
locked.set(false);
LockSupport.unpark(waiters.peek());
}
}
修飾子と型 | メソッドと説明 |
---|---|
static Object |
getBlocker(Thread t)
まだブロック解除されていないparkメソッドの最新の呼出しに指定されたブロッカ・オブジェクトを返します。ブロックされていない場合はnullを返します。
|
static void |
park()
パーミットが利用可能でない場合、スレッドのスケジューリングに関して現在のスレッドを無効にします。
|
static void |
park(Object blocker)
パーミットが利用可能でない場合、スレッドのスケジューリングに関して現在のスレッドを無効にします。
|
static void |
parkNanos(long nanos)
パーミットが利用可能である場合を除き、現在のスレッドを、指定された待機時間までスレッド・スケジューリングに関して無効にします。
|
static void |
parkNanos(Object blocker, long nanos)
パーミットが利用可能である場合を除き、現在のスレッドを、指定された待機時間までスレッド・スケジューリングに関して無効にします。
|
static void |
parkUntil(long deadline)
パーミットが利用可能でない場合、指定された期限まで、スレッドのスケジューリングに関して現在のスレッドを無効にします。
|
static void |
parkUntil(Object blocker, long deadline)
パーミットが利用可能でない場合、指定された期限まで、スレッドのスケジューリングに関して現在のスレッドを無効にします。
|
static void |
unpark(Thread thread)
指定されたスレッドのパーミットが使用可能でない場合に、使用可能にします。
|
public static void unpark(Thread thread)
park
でブロックされた場合は、ブロックを解除します。それ以外の場合は、そのpark
の次回の呼出しがブロックされないよう保証されます。指定されたスレッドが起動していない場合、この操作の効果は一切保証されません。thread
- unparkを実行するスレッドまたはnull
。その場合、この操作に効果はないpublic static void park(Object blocker)
パーミットが使用可能な場合、これは消費され、呼出しはただちに復帰します。それ以外の場合、現在のスレッドは、スレッド・スケジューリングに関して無効になり、次の3つのいずれかが起きるまで待機します。
このメソッドは、これらのどれがメソッド復帰の原因となったかはレポートしません。呼出し側は、スレッドの初回parkの原因となった状態を再チェックする必要があります。呼出し側は、復帰時のスレッドの割込み状態なども判定できます。
blocker
- このスレッドのparkを行う同期オブジェクトpublic static void parkNanos(Object blocker, long nanos)
パーミットが使用可能な場合、これは消費され、呼出しはただちに復帰します。それ以外の場合、現在のスレッドは、スレッド・スケジューリングに関して無効になり、次の4つのいずれかが起きるまで待機します。
unpark
を呼び出す。
このメソッドは、これらのどれがメソッド復帰の原因となったかはレポートしません。呼出し側は、スレッドの初回parkの原因となった状態を再チェックする必要があります。呼出し側は、スレッドの割込み状態や、復帰時の経過時間なども判定できます。
blocker
- このスレッドのparkを行う同期オブジェクトnanos
- 待機する最大ナノ秒数public static void parkUntil(Object blocker, long deadline)
パーミットが使用可能な場合、これは消費され、呼出しはただちに復帰します。それ以外の場合、現在のスレッドは、スレッド・スケジューリングに関して無効になり、次の4つのいずれかが起きるまで待機します。
unpark
を呼び出す。
このメソッドは、これらのどれがメソッド復帰の原因となったかはレポートしません。呼出し側は、スレッドの初回parkの原因となった状態を再チェックする必要があります。呼出し側は、スレッドの割込み状態や、復帰時の現在時刻なども判定できます。
blocker
- このスレッドのparkを行う同期オブジェクトdeadline
- 待機用の、元期からのミリ秒単位の絶対時間public static Object getBlocker(Thread t)
t
- スレッドNullPointerException
- 引数がnullの場合public static void park()
パーミットが使用可能な場合、これは消費され、呼出しはただちに復帰します。それ以外の場合、現在のスレッドは、スレッド・スケジューリングに関して無効になり、次の3つのいずれかが起きるまで待機します。
このメソッドは、これらのどれがメソッド復帰の原因となったかはレポートしません。呼出し側は、スレッドの初回parkの原因となった状態を再チェックする必要があります。呼出し側は、復帰時のスレッドの割込み状態なども判定できます。
public static void parkNanos(long nanos)
パーミットが使用可能な場合、これは消費され、呼出しはただちに復帰します。それ以外の場合、現在のスレッドは、スレッド・スケジューリングに関して無効になり、次の4つのいずれかが起きるまで待機します。
unpark
を呼び出す。
このメソッドは、これらのどれがメソッド復帰の原因となったかはレポートしません。呼出し側は、スレッドの初回parkの原因となった状態を再チェックする必要があります。呼出し側は、スレッドの割込み状態や、復帰時の経過時間なども判定できます。
nanos
- 待機する最大ナノ秒数public static void parkUntil(long deadline)
パーミットが使用可能な場合、これは消費され、呼出しはただちに復帰します。それ以外の場合、現在のスレッドは、スレッド・スケジューリングに関して無効になり、次の4つのいずれかが起きるまで待機します。
unpark
を呼び出す。
このメソッドは、これらのどれがメソッド復帰の原因となったかはレポートしません。呼出し側は、スレッドの初回parkの原因となった状態を再チェックする必要があります。呼出し側は、スレッドの割込み状態や、復帰時の現在時刻なども判定できます。
deadline
- 待機用の、元期からのミリ秒単位の絶対時間 バグまたは機能を送信
詳細なAPIリファレンスおよび開発者ドキュメントについては、Java SEのドキュメントを参照してください。そのドキュメントには、概念的な概要、用語の定義、回避方法、有効なコード例などの、開発者を対象にしたより詳細な説明が含まれています。
Copyright© 1993, 2014, Oracle and/or its affiliates. All rights reserved.