クラスLockSupport

java.lang.Object
java.util.concurrent.locks.LockSupport

public finalクラスLockSupportオブジェクトを拡張します。
ロックおよびほかの同期クラスを作成するための、基本的なスレッド・ブロック・プリミティブです。

このクラスは、それを使用している各スレッドにパーミットを(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()) {
  // ensure request to unpark is visible to other threads
  ...
  LockSupport.park(this);
}
ここで、parkへのコールの前に、アン・パークするリクエストを発行するスレッドによるアクションは、ロックまたはブロックを伴います。 各スレッドには1つの許可のみが関連付けられているため、クラス・ロードを介して暗黙的にparkを仲介的に使用すると、応答しないスレッド(a "敗北")が発生する可能性があります。

使用例 次に、先入れ先出しの再入不可能なロック・クラスの概略を示します。

class FIFOMutex {
  private final AtomicBoolean locked = new AtomicBoolean(false);
  private final Queue<Thread> waiters
    = new ConcurrentLinkedQueue<>();

  public void lock() {
    boolean wasInterrupted = false;
    // publish current thread for unparkers
    waiters.add(Thread.currentThread());

    // Block while not first in queue or cannot acquire lock
    while (waiters.peek() != Thread.currentThread() ||
           !locked.compareAndSet(false, true)) {
      LockSupport.park(this);
      // ignore interrupts while waiting
      if (Thread.interrupted())
        wasInterrupted = true;
    }

    waiters.remove();
    // ensure correct interrupted status on return
    if (wasInterrupted)
      Thread.currentThread().interrupt();
  }

  public void unlock() {
    locked.set(false);
    LockSupport.unpark(waiters.peek());
  }

  static {
    // Reduce the risk of "lost unpark" due to classloading
    Class<?> ensureLoaded = LockSupport.class;
  }
}

導入されたバージョン:
1.5
  • メソッドのサマリー

    修飾子と型
    メソッド
    説明
    static Object
    まだブロック解除されていないparkメソッドの最新の呼出しに指定されたブロッカ・オブジェクトを返します。ブロックされていない場合はnullを返します。
    static void
    パーミットが利用可能でない場合、スレッドのスケジューリングに関して現在のスレッドを無効にします。
    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
    現行のスレッドのgetBlockerの呼出しで返されるオブジェクトを設定します。
    static void
    unpark(Thread thread)
    指定されたスレッドのパーミットが使用可能でない場合に、使用可能にします。

    クラスオブジェクトで宣言されたメソッド

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    修飾子と型
    メソッド
    説明
    protected Object
    このオブジェクトのコピーを作成して、返します。
    boolean
    このオブジェクトと他のオブジェクトが等しいかどうかを示します。
    protected void
    削除予定のため非推奨: このAPI要素は、将来のバージョンで削除される可能性があります。
    最終決定は非推奨であり、将来のリリースで削除される可能性があります。
    final Class<?>
    このObjectの実行時クラスを返します。
    int
    このオブジェクトに対するハッシュ・コード値を返します。
    final void
    このオブジェクトのモニターで待機中のスレッドを1つ再開します。
    final void
    このオブジェクトのモニターで待機中のすべてのスレッドを再開します。
    オブジェクトの文字列表現を返します。
    final void
    現在のスレッドが目覚めるまで待機します。通常、notifiedまたはinterruptedです。
    final void
    wait(long timeoutMillis)
    現在のスレッドは、通常、notifiedまたはinterruptedであるか、一定のリアルタイムが経過するまで、目覚めるまで待機します。
    final void
    wait(long timeoutMillis, int nanos)
    現在のスレッドは、通常、notifiedまたはinterruptedであるか、一定のリアルタイムが経過するまで、目覚めるまで待機します。
  • メソッドの詳細

    • setCurrentBlocker

      public static void setCurrentBlocker(Object blocker)
      現行のスレッドのgetBlockerの呼出しで返されるオブジェクトを設定します。 このメソッドは、非パブリック・オブジェクトからpark()の引数なしのバージョンを起動する前に使用でき、より役立つ診断を可能にし、以前のブロックしているメソッドの実装との互換性を維持します。 ブロッカの前の値は、ブロック後に自動的にリストアされません。 park(bの効果を得るには、 setCurrentBlocker(b); park(); setCurrentBlocker(null);を使用
      パラメータ:
      blocker - ブロッカ・オブジェクト
      導入されたバージョン:
      14
    • unpark

      public static void unpark(Thread thread)
      指定されたスレッドのパーミットが使用可能でない場合に、使用可能にします。 スレッドがparkでブロックされた場合は、ブロックを解除します。 それ以外の場合は、そのparkの次回の呼出しがブロックされないよう保証されます。 指定されたスレッドが起動していない場合、この操作の効果は一切保証されません。
      パラメータ:
      thread - unparkを実行するスレッドまたはnull。その場合、この操作に効果はない
    • park

      public static void park(Object blocker)
      パーミットが利用可能でない場合、スレッドのスケジューリングに関して現在のスレッドを無効にします。

      パーミットが使用可能な場合、これは消費され、呼出しはただちに復帰します。それ以外の場合、現在のスレッドは、スレッド・スケジューリングに関して無効になり、次の3つのいずれかが起きるまで待機します。

      • ほかのスレッドが、現在のスレッドをターゲットとしてunparkを呼び出す。
      • ほかのスレッドが現在のスレッドに割り込みを行う。または
      • 呼出しが、見せかけで(理由もなく)復帰する。

      このメソッドは、これらのどれがメソッド復帰の原因となったかはレポートしません 呼出し側は、スレッドの初回parkの原因となった状態を再チェックする必要があります。 呼び出し元は、たとえば、リターン時のスレッドの中断ステータスを決定することもできます。

      パラメータ:
      blocker - このスレッドのparkを行う同期オブジェクト
      導入されたバージョン:
      1.6
    • parkNanos

      public static void parkNanos(Object blocker, long nanos)
      パーミットが利用可能である場合を除き、現在のスレッドを、指定された待機時間までスレッド・スケジューリングに関して無効にします。

      指定した待機時間がゼロまたは負の場合、メソッドは何も実行しません。 それ以外の場合、許可が消費され、呼出しはただちに返されます。それ以外の場合は、現在のスレッドがスレッドのスケジューリングに関して無効になり、4つのうちの1つが起きるまで待機します:

      • ほかのスレッドが、現在のスレッドをターゲットとしてunparkを呼び出す。
      • ほかのスレッドが現在のスレッドに割り込みを行う。または
      • 指定された待機時間が経過する。または
      • 呼出しが、見せかけで(理由もなく)復帰する。

      このメソッドは、これらのどれがメソッド復帰の原因となったかはレポートしません 呼出し側は、スレッドの初回parkの原因となった状態を再チェックする必要があります。 また、呼出し側は、スレッドの中断ステータスや戻り時の経過時間などを判断することもできます。

      パラメータ:
      blocker - このスレッドのparkを行う同期オブジェクト
      nanos - 待機する最大ナノ秒数
      導入されたバージョン:
      1.6
    • parkUntil

      public static void parkUntil(Object blocker, long deadline)
      パーミットが利用可能でない場合、指定された期限まで、スレッドのスケジューリングに関して現在のスレッドを無効にします。

      パーミットが使用可能な場合、これは消費され、呼出しはただちに復帰します。それ以外の場合、現在のスレッドは、スレッド・スケジューリングに関して無効になり、次の4つのいずれかが起きるまで待機します。

      • ほかのスレッドが、現在のスレッドをターゲットとしてunparkを呼び出す。
      • ほかのスレッドが現在のスレッドに割り込みを行う。または
      • 指定された期限が経過する。または
      • 呼出しが、見せかけで(理由もなく)復帰する。

      このメソッドは、これらのどれがメソッド復帰の原因となったかはレポートしません 呼出し側は、スレッドの初回parkの原因となった状態を再チェックする必要があります。 呼び出し元は、たとえば、スレッドの中断ステータスや戻り時の現在の時間などを判断することもできます。

      パラメータ:
      blocker - このスレッドのparkを行う同期オブジェクト
      deadline - 待機用の、元期からのミリ秒単位の絶対時間
      導入されたバージョン:
      1.6
    • getBlocker

      public static Object getBlocker(Thread t)
      まだブロック解除されていないparkメソッドの最新の呼出しに指定されたブロッカ・オブジェクトを返します。ブロックされていない場合はnullを返します。 返される値は、瞬間的なスナップショットです。そのため、スレッドは別のブロッカ・オブジェクトでブロック解除されていることもブロックされていることもあります。
      パラメータ:
      t - スレッド
      戻り値:
      ブロッカ
      スロー:
      NullPointerException - 引数がnullの場合
      導入されたバージョン:
      1.6
    • park

      public static void park()
      パーミットが利用可能でない場合、スレッドのスケジューリングに関して現在のスレッドを無効にします。

      パーミットが使用可能な場合、これは消費され、呼出しはただちに復帰します。それ以外の場合、現在のスレッドは、スレッド・スケジューリングに関して無効になり、次の3つのいずれかが起きるまで待機します。

      • ほかのスレッドが、現在のスレッドをターゲットとしてunparkを呼び出す。
      • ほかのスレッドが現在のスレッドに割り込みを行う。または
      • 呼出しが、見せかけで(理由もなく)復帰する。

      このメソッドは、これらのどれがメソッド復帰の原因となったかはレポートしません 呼出し側は、スレッドの初回parkの原因となった状態を再チェックする必要があります。 呼び出し元は、たとえば、リターン時のスレッドの中断ステータスを決定することもできます。

    • parkNanos

      public static void parkNanos(long nanos)
      パーミットが利用可能である場合を除き、現在のスレッドを、指定された待機時間までスレッド・スケジューリングに関して無効にします。

      指定した待機時間がゼロまたは負の場合、メソッドは何も実行しません。 それ以外の場合、許可が消費され、呼出しはただちに返されます。それ以外の場合は、現在のスレッドがスレッドのスケジューリングに関して無効になり、4つのうちの1つが起きるまで待機します:

      • ほかのスレッドが、現在のスレッドをターゲットとしてunparkを呼び出す。
      • ほかのスレッドが現在のスレッドに割り込みを行う。または
      • 指定された待機時間が経過する。または
      • 呼出しが、見せかけで(理由もなく)復帰する。

      このメソッドは、これらのどれがメソッド復帰の原因となったかはレポートしません 呼出し側は、スレッドの初回parkの原因となった状態を再チェックする必要があります。 また、呼出し側は、スレッドの中断ステータスや戻り時の経過時間などを判断することもできます。

      パラメータ:
      nanos - 待機する最大ナノ秒数
    • parkUntil

      public static void parkUntil(long deadline)
      パーミットが利用可能でない場合、指定された期限まで、スレッドのスケジューリングに関して現在のスレッドを無効にします。

      パーミットが使用可能な場合、これは消費され、呼出しはただちに復帰します。それ以外の場合、現在のスレッドは、スレッド・スケジューリングに関して無効になり、次の4つのいずれかが起きるまで待機します。

      • ほかのスレッドが、現在のスレッドをターゲットとしてunparkを呼び出す。
      • ほかのスレッドが現在のスレッドに割り込みを行う。または
      • 指定された期限が経過する。または
      • 呼出しが、見せかけで(理由もなく)復帰する。

      このメソッドは、これらのどれがメソッド復帰の原因となったかはレポートしません 呼出し側は、スレッドの初回parkの原因となった状態を再チェックする必要があります。 呼び出し元は、たとえば、スレッドの中断ステータスや戻り時の現在の時間などを判断することもできます。

      パラメータ:
      deadline - 待機用の、元期からのミリ秒単位の絶対時間