1 概述
是一个工具类,主要作用就是挂起和唤醒线程,内部是调用了Unsafe的方法来实现的,其组成如下图所示。调用LockSupport类的线程会与该类关联一个许可证,默认情况下该类是不持有该许可证的。
下面对其中的一些主要方法进行介绍
2 挂起线程的方法
2.1 park()
如果调用park()方法的线程已经持有许可证则调用该方法时会立马返回,否则调用该方法的线程会被阻塞挂起。注意因调用park()方法而被阻塞的线程被其他线程中断返回时并不会抛出InterruptedException。
2.2 parkNanos(long nanos)
与park()方法不同之处在于,调用该方法的线程在未持有许可证被挂起后,若在时间nanos没被唤醒也会在nanos时间到后自己返回
2.3 park(Object blocker)
线程类有一个parkObject成员变量,调用该park方法会设置该线程的parkObject成员变量并将该线程挂起。当然,若线程持有许可证也会立马返回。
2.4 parkNanos(Object blocker, long nanos)
与park(Object blocker)方法相比就是多了一个超时时间,到了超时时间会自己返回
2.5 parkUntil(Object blocker, long deadline)
该方法中的deadline计算的是从1970年到现在某一个时间点的毫秒值
3 唤醒线程的方法
unpark(Thread thread)
当一个线程调用unpark(),如果参数线程thread没有持有thread与LockSupport关联的许可证,则使其持有该许可证。如果thread之前因为调用park()方法而被挂起,则立即唤醒该线程。如果该线程之前没有调用park()方法,则在调用park()方法后会立刻返回。
4 使用
接下来通过一段代码来看以下park()和unpark()方法的使用
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " 要调用park挂起了");
LockSupport.park();
System.out.println(Thread.currentThread().getName() + " 因其他线程调用unpark()方法返回了");
});
thread.start();
try {
Thread.sleep(1000);//保证thread调用了park()方法
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "要唤醒thread了");
LockSupport.unpark(thread);
System.out.println(Thread.currentThread().getName() + "结束");
}
/*最后输出结果 Thread-0 要调用park挂起了
main要唤醒thread了
main结束
Thread-0 因其他线程调用unpark()方法返回了*/