LockSupport与线程阻塞唤醒
1. park /unpark 工作机制
LockSupport.park()
阻塞当前线程,直到被 unpark 或线程中断。
LockSupport.unpark(Thread t)
给指定线程发放一个「许可」,让它从 park 中返回。
核心机制:许可机制(类似 0/1 信号量)
LockSupport.park()
尝试拿走这张令牌
- 当前令牌 = 1:拿走令牌 → 令牌变 0 → 直接放行,不阻塞
- 当前令牌 = 0:拿不到 → 线程阻塞挂起,原地等着
LockSupport.unpark (线程)
给目标线程发一张令牌
- 原本 0 → 改成 1
- 原本已经是 1 → 不变,还是 1,不叠加
场景 1:先 park,后 unpark
线程 A 执行
park()此时许可 = 0,拿不到令牌 → 阻塞卡住
其他线程执行
unpark(A)给 A 发许可,许可变成 1
被卡住的 A 立刻醒来,消耗掉许可(许可变回 0)
1 | |
场景 2:先 unpark,后 park(重点、难点)
其他线程提前执行
unpark(A)A 的许可直接变成 1
过一会,线程 A 才执行
park()一看:有许可(1),直接拿走、消耗掉
→ 完全不阻塞,直接往下执行
1 | |
1 | |
2. 与 wait/notify 的核心区别
| 对比 | wait/notify | park/unpark |
|---|---|---|
| 前置条件 | 必须在 synchronized 内部 |
任意地方可用 |
| 执行顺序 | notify 必须在 wait 后,否则永久等待 | unpark 可先于 park,不会卡死 |
| 目标 | 随机唤醒一个 / 全部唤醒 | 精准唤醒指定线程 |
| 锁释放 | 释放锁 | 不涉及锁,只阻塞线程 |
| 中断 | 不响应中断(只会抛异常) | 可响应中断,不会抛异常 |
一句话总结:
park/unpark 更灵活、更精准、顺序不敏感、无锁限制。
3. AQS 底层依赖的阻塞工具
AQS(AbstractQueuedSynchronizer) 是 Java 锁的基石:
ReentrantLock、CountDownLatch、Semaphore 等都基于它。
AQS 内部线程排队、阻塞与唤醒,完全依赖:
LockSupport.park()LockSupport.unpark()
所以:
LockSupport 是整个 JUC 同步组件的底层阻塞原语。
LockSupport与线程阻塞唤醒
http://hanqichuan.com/2026/04/15/java并发/LockSupport与线程阻塞唤醒/