此类与使用它的每个线程关联一个许可(在 Semaphore 类的意义上)。如果许可可用,对 park 的调用将立即返回,并在此过程中消耗它;否则它may块。如果许可尚不可用,则调用 unpark 可使许可可用。 (虽然与信号量不同,许可不会累积。最多只有一个。)可靠的使用需要使用易失性(或原子)变量来控制何时停放或取消停放。对这些方法的调用顺序是根据易失性变量访问来维护的,但不一定是非易失性变量访问。
方法 park 和 unpark 提供了阻塞和解除阻塞线程的有效方法,这些线程不会遇到导致已弃用方法 Thread.suspend 和 Thread.resume 无法用于此类目的的问题:一个线程调用 park 和另一个线程尝试调用 unpark 之间的竞争将保持活性,由于许可证。此外,如果调用者的线程被中断,park 将返回,并且支持超时版本。 park 方法也可能在任何其他时间“无故”返回,因此通常必须在返回时重新检查条件的循环中调用。从这个意义上说,park 是对“忙等待”的优化,它不会浪费太多时间,但必须与 unpark 配对才能有效。
park 的三种形式各自还支持一个 blocker 对象参数。在线程被阻塞时记录此对象,以允许监视和诊断工具识别线程被阻塞的原因。 (此类工具可能会使用方法 getBlocker(Thread) 访问阻止程序。)强烈建议使用这些形式而不是没有此参数的原始形式。在锁实现中作为 blocker 提供的正常参数是 this 。
这些方法旨在用作创建更高级别同步实用程序的工具,它们本身对大多数并发控制应用程序没有用处。 park 方法仅用于以下形式的构造:
while (!canProceed()) {
// ensure request to unpark is visible to other threads
...
LockSupport.park(this);
} 其中,在调用 park 之前,发布请求取消停放的线程没有执行任何操作,需要锁定或阻塞。因为只有一个许可与每个线程相关联,所以 park 的任何中间使用,包括通过类加载隐式使用,都可能导致线程无响应(“丢失的解锁”)。
示例用法。这是一个先进先出的不可重入锁类的草图:
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 interrupt 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 ObjectgetBlocker(Thread t) 返回提供给最近一次调用尚未解除阻塞的 park 方法的阻塞对象,如果未被阻塞则返回 null。static voidpark()除非许可可用,否则出于线程调度目的禁用当前线程。static void除非许可可用,否则出于线程调度目的禁用当前线程。static voidparkNanos(long nanos) 出于线程调度目的禁用当前线程,直到指定的等待时间,除非许可可用。static void出于线程调度目的禁用当前线程,直到指定的等待时间,除非许可可用。static voidparkUntil(long deadline) 出于线程调度目的禁用当前线程,直到指定的截止日期,除非许可可用。static void出于线程调度目的禁用当前线程,直到指定的截止日期,除非许可可用。static voidsetCurrentBlocker(Object blocker) 设置要由当前线程调用getBlocker返回的对象。static void使给定线程的许可可用(如果它尚不可用)。
-
方法详情
-
setCurrentBlocker
设置要由当前线程调用getBlocker返回的对象。在从非公共对象调用park()的无参数版本之前,可以使用此方法,从而允许进行更有用的诊断,或保持与以前的阻塞方法实现的兼容性。阻止程序的先前值在阻止后不会自动恢复。要获得park(b} 的效果,请使用setCurrentBlocker(b); park(); setCurrentBlocker(null);- 参数:
blocker- 阻塞对象- 自从:
- 14
-
unpark
使给定线程的许可可用(如果它尚不可用)。如果线程在park上被阻塞,那么它将解除阻塞。否则,它对park的下一次调用保证不会阻塞。如果给定线程尚未启动,则不能保证此操作有任何效果。- 参数:
thread- 要取消停放的线程,或null,在这种情况下此操作无效
-
park
除非许可可用,否则出于线程调度目的禁用当前线程。如果许可证可用,则使用它并立即返回调用;否则,当前线程出于线程调度目的而被禁用并处于休眠状态,直到发生以下三种情况之一:
此方法会not 报告其中哪些导致该方法返回。调用者应该首先重新检查导致线程停放的条件。调用者还可以确定,例如,返回时线程的中断状态。
- 参数:
blocker- 负责此线程停放的同步对象- 自从:
- 1.6
-
parkNanos
出于线程调度目的禁用当前线程,直到指定的等待时间,除非许可可用。如果指定的等待时间为零或负数,则该方法不执行任何操作。否则,如果许可证可用,则使用它并立即返回调用;否则,当前线程出于线程调度目的而被禁用并处于休眠状态,直到发生以下四种情况之一:
此方法会not 报告其中哪些导致该方法返回。调用者应该首先重新检查导致线程停放的条件。调用者还可以确定,例如,线程的中断状态,或返回时经过的时间。
- 参数:
blocker- 负责此线程停放的同步对象nanos- 等待的最大纳秒数- 自从:
- 1.6
-
parkUntil
出于线程调度目的禁用当前线程,直到指定的截止日期,除非许可可用。如果许可证可用,则使用它并立即返回调用;否则,当前线程出于线程调度目的而被禁用并处于休眠状态,直到发生以下四种情况之一:
此方法会not 报告其中哪些导致该方法返回。调用者应该首先重新检查导致线程停放的条件。调用者还可以确定,例如,线程的中断状态,或返回时的当前时间。
- 参数:
blocker- 负责此线程停放的同步对象deadline- 等待的绝对时间,从纪元开始以毫秒为单位- 自从:
- 1.6
-
getBlocker
返回提供给最近一次调用尚未解除阻塞的 park 方法的阻塞对象,如果未被阻塞则返回 null。返回的值只是一个瞬间快照——线程可能在不同的阻塞对象上解除阻塞或阻塞。- 参数:
t- 线程- 返回:
- 阻碍者
- 抛出:
NullPointerException- 如果参数为空- 自从:
- 1.6
-
park
public static void park() -
parkNanos
public static void parkNanos(long nanos) 出于线程调度目的禁用当前线程,直到指定的等待时间,除非许可可用。如果指定的等待时间为零或负数,则该方法不执行任何操作。否则,如果许可证可用,则使用它并立即返回调用;否则,当前线程出于线程调度目的而被禁用并处于休眠状态,直到发生以下四种情况之一:
此方法会not 报告其中哪些导致该方法返回。调用者应该首先重新检查导致线程停放的条件。调用者还可以确定,例如,线程的中断状态,或返回时经过的时间。
- 参数:
nanos- 等待的最大纳秒数
-
parkUntil
public static void parkUntil(long deadline) 出于线程调度目的禁用当前线程,直到指定的截止日期,除非许可可用。如果许可证可用,则使用它并立即返回调用;否则,当前线程出于线程调度目的而被禁用并处于休眠状态,直到发生以下四种情况之一:
此方法会not 报告其中哪些导致该方法返回。调用者应该首先重新检查导致线程停放的条件。调用者还可以确定,例如,线程的中断状态,或返回时的当前时间。
- 参数:
deadline- 等待的绝对时间,从纪元开始以毫秒为单位
-