LockSupport.park和unpark是JVM提供的底层线程阻塞/唤醒原语,基于单许可机制实现无锁、精准唤醒,不依赖synchronized或对象监视器,被ReentrantLock等高级同步工具所构建。

LockSupport.park 和 unpark 并不“实现锁机制”,而是提供底层线程阻塞/唤醒原语,JDK 中的 ReentrantLock、Condition、CountDownLatch 等高级同步工具正是基于它们构建的。它本身不是锁,但比 synchronized 更灵活:无需配对的 monitor enter/exit,支持精准唤醒指定线程,且不依赖对象监视器(即不用 synchronized 块包裹)。
park/unpark 的核心特性:无锁、单线程、许可制
LockSupport 的行为基于一个隐式的“许可”(permit)——每个线程最多持有一个许可,初始为 0:
- unpark(Thread t):给 t 发送一个许可(若 t 尚未持有),t 后续调用 park 会直接返回,不阻塞;若 t 已在 park 中,则立即被唤醒。
- park():若当前线程有许可,消耗掉并立即返回;否则挂起线程,直到被 unpark 或被中断。
- 许可不可叠加:多次 unpark 只保留一个许可,不会累积(这点和信号量不同)。
- 不关联任何对象或 synchronized 块,也不抛出 InterruptedException(但可响应中断状态)。
为什么能绕过 synchronized?——因为它不操作 monitor
synchronized 阻塞依赖 JVM 的 monitor 机制(进入 wait set、竞争 entry set),必须配合 synchronized 块或方法使用。而 park/unpark 是 JVM 提供的更底层的线程调度指令,直接作用于线程状态(RUNNABLE ↔ WAITING),完全独立于 Java 对象锁。例如:
// 不需要 synchronized,也不需要任何锁对象
Thread t = new Thread(() -> {
System.out.println("准备 park");
LockSupport.park(); // 挂起自己
System.out.println("被唤醒");
});
t.start();
Thread.sleep(100);
LockSupport.unpark(t); // 主动唤醒 t
这段代码没有 synchronized、没有 wait/notify、也没有显式 Lock,却实现了线程精准控制。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
如何用 park/unpark 构建简易可重入锁(示意逻辑)
以 ReentrantLock 的公平模式简化版为例,说明它如何替代 synchronized 实现锁语义:
- 维护一个 volatile owner 字段记录当前持有锁的线程;
- acquire 时:若 owner 为空,CAS 设置成功则获取锁;否则将当前线程加入等待队列,并调用 park() 挂起;
- release 时:清空 owner,并对队列头节点调用 unpark() —— 仅唤醒一个线程,且是精确到该节点对应线程;
- 整个过程无需 synchronized,靠 CAS + volatile + park/unpark 组合保证可见性与原子性。
关键点在于:park 发生在 acquire 失败后,unpark 发生在 release 成功后,两者通过共享状态(如 owner、队列节点)协调,而非 monitor 协议。
注意事项:易错点与最佳实践
park/unpark 强大但容易误用:
- park 前未检查条件可能导致虚假唤醒或永久挂起(应配合循环检查条件,类似 while(parkCondition) park());
- unpark 提前调用(先 unpark 后 park)是安全的(许可保留),但若多次 unpark 后只 park 一次,多余许可会丢失;
- park 不响应中断,但可通过 Thread.interrupted() 检查中断状态,建议结合 interrupted 标志做退出判断;
- 不要用它直接替代 synchronized 写业务逻辑——它太底层,应优先使用 ReentrantLock、Semaphore 等封装好的工具类。

















