locksupport.park()和unpark()基于线程内permit机制实现精准阻塞唤醒:unpark设permit为1(可提前),park消耗permit或挂起;需循环检查条件、用volatile保证可见性,支持中断响应与超时控制。

Java 多线程中,LockSupport.park() 和 LockSupport.unpark(Thread) 是 JVM 提供的底层线程阻塞与唤醒原语,不依赖锁、不需 synchronized、也不关联对象监视器,能实现线程级的精准控制。
park/unpark 的核心机制是“许可(permit)”
每个线程内部持有一个二值许可状态:0 或 1,初始为 0。
-
调用
unpark(t):将目标线程t的 permit 设为 1(若已是 1,则无变化);如果t正在park()中,会立刻被唤醒;如果t尚未 park,该许可会“保留”,下次调用park()时直接消耗并返回,不会挂起。 -
调用
park():检查当前线程 permit。为 1 则置为 0 并立即返回;为 0 则线程进入 WAITING 状态,等待被 unpark 或中断。 -
permit 不可累积:连续两次
unpark(t)和一次park(),效果等同于一次unpark+ 一次park。
如何安全地挂起一个线程
不能裸调 park(),必须配合业务条件判断,防止虚假唤醒或永久阻塞。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 使用
volatile变量或原子类型记录状态,确保可见性。 - 采用“循环检查 + park”模式:先检查条件是否满足,不满足再 park。
- 示例:
volatile boolean ready = false;
Thread t = new Thread(() -> {
while (!ready) {
LockSupport.park(); // 条件不满足才挂起
}
System.out.println("执行后续逻辑");
});
如何精准唤醒指定线程
unpark() 必须传入目标 Thread 对象引用,不能靠名字、ID 或猜测。
- 线程启动后尽早保存其引用,避免因 GC 或生命周期结束导致失效。
- 唤醒操作可提前执行(先
unpark后park),不会丢失信号——这是它比wait/notify更可靠的关键。 - 示例:
t.start();
Thread.sleep(50);
ready = true;
LockSupport.unpark(t); // 明确唤醒 t
处理中断与超时场景
park() 不抛 InterruptedException,但会响应中断状态。
- 调用后可用
Thread.interrupted()检查是否被中断,并决定是否退出等待。 - 有时间约束时,优先用
parkNanos(long)或parkUntil(long),避免无限等待。 - 注意:
park()被中断后,permit 不会被清空(与unpark无关),仅设置中断标志位。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










