park(Object blocker) 和 unpark(Thread thread) 方法位于Java 并发包下的 java.util.concurrent.locks.LockSupport 类,本质上是对 Unsafe 的 park/unpark 方法的简单封装,它是 Lock(AQS)的基石,给 Lock(AQS)提供了挂起/恢复当前线程的能力。
- // 暂停当前线程
- LockSupport.park();
-
- // 恢复某个线程的运行
- LockSupport.unpark(暂停线程对象)
- public static void main(String[] args) throws Exception {
- Thread t1 = new Thread(() -> {
- log.info("开始");
- Thread.sleep(1000);
- log.info("park");
- LockSupport.park();
- log.info("结束");
- }, "t1");
- t1.start();
-
- Thread.sleep(1000);
- log.info("unpark");
- LockSupport.unpark(t1);
- }
每个线程都会关联一个 Parker 对象,每个 Parker 对象都各自维护了三个角色:计数器、互斥量、条件变量。
park 操作:
获取当前线程关联的 Parker 对象。
将计数器置为 0,同时检查计数器的原值是否为 1,如果是则放弃后续操作。
在互斥量上加锁。
在条件变量上阻塞,同时释放锁并等待被其他线程唤醒,当被唤醒后,将重新获取锁。
当线程恢复至运行状态后,将计数器的值再次置为 0。
释放锁。
unpark 操作:
获取目标线程关联的 Parker 对象(注意目标线程不是当前线程)。
在互斥量上加锁。
将计数器置为 1。
唤醒在条件变量上等待着的线程。
释放锁。