LockSupport 使用说明
在看JUC包下源码时发现很多的线程的阻塞运行都通过park方法和unpark方法控制,尤其在看AQS源码时发现很多地方都会用到此类 ,首先我们通过api文档简单了解下该类
一下为api文档节选
- 线程阻塞原语用于实现锁和用于实现同步类
- 该类持有一个permit可供任意线程使用,permit只有0,1两种状态,park操作将permit从1变为0,unpark与之相反
- park与unpark不会像Thread.suspend方法和Thread.resume方法出现死锁问题
- park提供blocker对象参数用于问题定位
以AQS源码中为例此方法支持中断判断,例如可重入锁中支持中断的加锁方式在当前线程被中断唤醒后如果检查中断标识位为true可以抛出中断异常
private final boolean parkAndCheckInterrupt() {
LockSupport.park(this);
return Thread.interrupted();
}
该类提供了带有超时时间的park方法针对忙则等待的一种优化,park与unpark方法只是将线程睡眠和唤醒而不释放锁
重要方法分析
unpark将permit由0变为1当前线程由block状态变为unblock状态。
public static void unpark(Thread thread) {
if (thread != null)
UNSAFE.unpark(thread);
}
park方法将permit由1变为0阻塞当前线程除非一下三种情况发生否则一直阻塞
- 其他线程调用unpark方法unblock该线程
- 该线程被其他线程中断。
- 该调用不合逻辑地(即毫无理由地)返回
public static void park(Object blocker) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
UNSAFE.park(false, 0L);
setBlocker(t, null);
}