当需要阻塞或者唤醒一个线程时,可以使用LockSupport工具类来完成。LockSupport定义了一组公共静态方法,这些方法提供了最基本的阻塞和唤醒功能。
api解释如下
用于创建锁和其他同步类的基本线程阻塞原语。
这个类与每个使用它的线程相关联,一个许可证(在Semaphore类的意义上)。 如果许可证可用,则呼叫park将park返回,在此过程中消耗它; 否则可能会阻止。 致电unpark使许可证可用,如果尚不可用。 (与信号量不同,许可证不能累积,最多只有一个。)
方法park和unpark提供了阻止和解除阻塞线程的有效手段,该方法不会遇到导致不推荐使用的方法Thread.suspend和Thread.resume目的不能使用的问题:一个线程调用park和另一个线程之间的尝试unpark线程将保持活跃性,由于许可证。 另外,如果调用者的线程被中断, park将返回,并且支持超时版本。 park方法也可以在任何其他时间返回,因为“无理由”,因此一般必须在返回之前重新检查条件的循环中被调用。 在这个意义上, park作为一个“忙碌等待”的优化,不浪费时间旋转,但必须与unpark配对才能有效。
park的三种形式也支持blocker对象参数。 线程被阻止时记录此对象,以允许监视和诊断工具识别线程被阻止的原因。 (此类工具可以使用方法getBlocker(Thread)访问阻止程序 。)强烈鼓励使用这些形式而不是没有此参数的原始形式。 在锁实现中作为blocker提供的正常参数是this 。
这些方法被设计为用作创建更高级同步实用程序的工具,并且本身对于大多数并发控制应用程序本身并不有用。 park方法仅用于形式的构造:
while (!canProceed()) { ... LockSupport.park(this); }
其中既不canProceed也没有任何其他动作之前的呼叫park需要锁定或阻止。因为只有一个许可证与每个线程相关联, park任何中介使用可能会干扰其预期效果。
方法摘要
Modifier and Type |
Method and Description |
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) 为给定的线程提供许可证(如果尚未提供)。 |
简单用法
import java.util.concurrent.locks.LockSupport; public class LockSupportTest { public static void main(String[] args) { final Thread thread = new Thread(new Runnable() { @Override public void run() { System.out.println("thread 已挂起"); //当前线程挂起 LockSupport.park(); //阻塞当前线程11纳秒 LockSupport.parkNanos(11); //阻塞当前线程1000毫秒 LockSupport.parkUntil(1000L); System.out.println("唤醒继续执行"); } }); thread.start(); //在使用LockSupport.unpark(thread);时, 注释掉LockSupport.unpark(thread); thread线程持续被挂起而阻塞 LockSupport.unpark(thread); } }