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(java.lang.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, 2013, Oracle and/or its affiliates. All rights reserved.