java.util.concurrent.locks

接口
java.lang.Object
  继承者 java.util.concurrent.locks.LockSupport

public class LockSupport
     
extends Object

用来创建锁和其他同步类的基本线程阻塞原语。

此类以及每个使用它的线程与一个许可关联(从 Semaphore 类的意义上说)。如果该许可可用,并且可在进程中使用,则调用 park 将立即返回;否则可能 阻塞。如果许可尚不可用,则可以调用 unpark 使其可用。(但与 Semaphore 不同的是,许可不能累积,并且最多只能有一个许可。)

parkunpark 方法提供了阻塞和解除阻塞线程的有效方法,并且不会遇到导致过时方法 Thread.suspendThread.resume 因为以下目的变得不可用的问题:由于许可的存在,调用 park 的线程和另一个试图将其 unpark 的线程之间的竞争将保持活性。此外,如果调用者线程被中断,并且支持超时,则 park 将返回。park 方法还可以在其他任何时间“毫无理由”地返回,因此通常必须在重新检查返回条件的循环里调用此方法。从这个意义上说,park 是“忙碌等待”的一种优化,它不会浪费这么多的时间进行自旋,但是必须将它与 unpark 配对使用才更高效。

三种形式的 park 还各自支持一个 blocker 对象参数。此对象在线程受阻塞时被记录,以允许监视工具和诊断工具确定线程受阻塞的原因。(这样的工具可以使用方法 getBlocker(java.lang.Thread) 访问 blocker。)建议最好使用这些形式,而不是不带此参数的原始形式。在锁实现中提供的作为 blocker 的普通参数是 this

这些方法被设计用来作为创建高级同步实用工具的工具,对于大多数并发控制应用程序而言,它们本身并不是很有用。park 方法仅设计用于以下形式的构造:

while (!canProceed()) { ... LockSupport.park(this); }
在这里,在调用 park 之前, canProceed 和其他任何动作都不会锁定或阻塞。因为每个线程只与一个许可关联, park 的任何中间使用都可能干扰其预期效果。

示例用法。 以下是一个先进先出 (first-in-first-out) 非重入锁类的框架。

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 方法调用的 blocker 对象,如果该调用不受阻塞,则返回 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)
          如果给定线程的许可尚不可用,则使其可用。
 
从类 java.lang.Object 继承的方法
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

方法详细信息

unpark

public static void unpark(Thread thread)
如果给定线程的许可尚不可用,则使其可用。如果线程在 park 上受阻塞,则它将解除其阻塞状态。否则,保证下一次调用 park 不会受阻塞。如果给定线程尚未启动,则无法保证此操作有任何效果。

参数:
thread - 要执行 unpark 操作的线程;该参数为 null 表示此操作没有任何效果。

park

public static void park(Object blocker)
为了线程调度,在许可可用之前禁用当前线程。

如果许可可用,则使用该许可,并且该调用立即返回;否则,为线程调度禁用当前线程,并在发生以下三种情况之一前,使其处于休眠状态:

  • 其他某个线程调用将当前线程作为目标调用 unpark;或者
  • 其他某个线程中断当前线程;或者
  • 该调用不合逻辑地(即毫无理由地)返回。

此方法 报告是哪个线程导致该方法返回。调用者应该重新检查最先导致线程暂停的条件。调用者还可以确定返回时该线程的中断状态。

参数:
blocker - 导致此线程暂停的同步对象
从以下版本开始:
1.6

parkNanos

public static void parkNanos(Object blocker,
                             long nanos)
为了线程调度,在许可可用前禁用当前线程,并最多等待指定的等待时间。

如果许可可用,则使用该许可,并且该调用立即返回;否则,为线程调度禁用当前线程,并在发生以下四种情况之一前,使其处于休眠状态:

  • 其他某个线程将当前线程作为目标调用 unpark;或者
  • 其他某个线程中断当前线程;或者
  • 已超过指定的等待时间;或者
  • 该调用不合逻辑地(即毫无理由地)返回。

此方法 报告是哪个线程导致该方法返回。调用者应该重新检查最先导致线程暂停的条件。调用者还可以确定返回时该线程的中断状态或已过的时间。

参数:
blocker - 导致此线程暂停的同步对象
nanos - 要等待的最大毫秒数
从以下版本开始:
1.6

parkUntil

public static void parkUntil(Object blocker,
                             long deadline)
为了线程调度,在指定的时限前禁用当前线程,除非许可可用。

如果许可可用,则使用该许可,并且该调用立即返回;否则,为线程调度禁用当前线程,并在发生以下四种情况之一前,使其处于休眠状态:

  • 其他某个线程将当前线程作为目标调用 unpark;或者
  • 其他某个线程中断当前线程;或者
  • 指定时限已过;或者
  • 该调用不合逻辑地(即毫无理由地)返回。

此方法 报告是哪个线程导致该方法返回。调用者应该重新检查最先导致线程暂停的条件。调用者还可以确定返回时该线程的中断状态或当前时间。

参数:
blocker - 导致此线程暂停的同步对象
deadline - 要等待的绝对时间,用相对于历元 (Epoch) 的毫秒数值表示
从以下版本开始:
1.6

getBlocker

public static Object getBlocker(Thread t)
返回提供给最近一次尚未解除阻塞的 park 方法调用的 blocker 对象,如果该调用不受阻塞,则返回 null。返回的值只是一个瞬间快照,即由于未解除阻塞或者在不同的 blocker 对象上受阻而具有的线程。

返回:
blocker
从以下版本开始:
1.6

park

public static void park()
为了线程调度,禁用当前线程,除非许可可用。

如果许可可用,则使用该许可,并且该调用立即返回;否则,为线程调度禁用当前线程,并在发生以下三种情况之一以前,使其处于休眠状态:

  • 其他某个线程将当前线程作为目标调用 unpark;或者
  • 其他某个线程中断当前线程;或者
  • 该调用不合逻辑地(即毫无理由地)返回。

此方法并 报告是哪个线程导致该方法返回。调用者应该重新检查最先导致线程暂停的条件。调用者还可以确定线程返回时的中断状态。


parkNanos

public static void parkNanos(long nanos)
为了线程调度禁用当前线程,最多等待指定的等待时间,除非许可可用。

如果许可可用,则使用该许可,并且该调用立即返回;否则,为线程调度禁用当前线程,并在发生以下四种情况之一以前,将其处于休眠状态:

  • 其他某个线程将当前线程作为目标调用 unpark;或者
  • 其他某个线程中断当前线程;或者
  • 已超过指定的等待时间;或者
  • 该调用不合逻辑地(即无缘无故地)返回。

此方法并 报告是哪个线程导致该方法返回。调用者应该重新检查最先导致线程暂停的条件。调用者还可以确定线程返回时的中断状态或所用的时间。

参数:
nanos - 要等待的最大毫秒数

parkUntil

public static void parkUntil(long deadline)
为了线程调度,在指定的时限前禁用当前线程,除非许可可用。

如果许可可用,则使用该许可,并且调用立即返回;否则,为线程调度禁用当前线程,并在发生以下四种情况之一以前,将其处于休眠状态:

  • 其他某个线程将当前线程作为目标调用 unpark;或者
  • 其他某个线程中断当前线程;或者
  • 指定的最后期限已过;或者
  • 该调用不合逻辑地(即毫无理由地)返回。

此方法并 报告是哪个线程导致该方法返回。调用者应该重新检查最先导致线程暂停的条件。调用者还可以确定线程返回时的中断状态或当前时间。

参数:
deadline - 要等待的绝对时间,用相对于历元的毫秒数值表示