locksupport是jvm线程调度的底层原语,基于permit机制实现线程挂起(park)与唤醒(unpark),不依赖锁、可先唤醒后挂起、精准指定线程,为aqs及reentrantlock等提供阻塞/唤醒能力。

Java 中的线程挂起与唤醒,LockSupport 并不直接实现锁机制,而是作为底层基础工具,为 java.util.concurrent 包中各类锁(如 ReentrantLock、AQS)提供“阻塞/唤醒”能力。它本质上是 JVM 对线程调度的轻量级封装,不依赖 synchronized,也不参与锁的获取/释放逻辑,只负责让一个线程在某个点暂停(park),并在合适时机恢复(unpark)。
LockSupport 的核心行为:park 与 unpark
LockSupport.park() 会让当前线程阻塞,直到发生以下任一情况:
- 其他线程对本线程调用
LockSupport.unpark(Thread) - 线程被中断(此时 park 会立即返回,且
Thread.interrupted()为 true) - 虚假唤醒(spurious wakeup),即无明确原因也返回(JVM 实现允许,需配合循环检查条件)
unpark(Thread) 是“许可”操作:每个线程内部持有一个隐式的许可(permit),初始为 0。调用 unpark 会将 permit 设为 1;若此时线程正 park 着,就会立刻被唤醒;若线程尚未 park,该许可会被保留,下次 park 时直接消费并立即返回——unpark 可以先于 park 调用,不会丢失。
为什么不用 wait/notify?
wait/notify 必须在 synchronized 块内使用,且依赖对象监视器(monitor),耦合度高、灵活性差。而 LockSupport:
- 无需同步块,可在任意上下文调用
- 作用目标明确(指定 Thread 对象),不依赖共享对象
- permit 机制天然支持“唤醒前置”,避免 notify 丢失问题
- 是 AQS 实现
acquire/release流程的核心支撑
在 AQS 中如何配合使用?
以 ReentrantLock 的非公平锁为例,线程抢锁失败后会进入 AQS 队列,并执行:
- 将当前节点入队 → 调用
LockSupport.park(this)挂起自己 - 当持有锁的线程释放锁时,AQS 会唤醒队首节点 → 调用
LockSupport.unpark(node.thread) - 被唤醒的线程重新尝试 CAS 抢锁,成功则继续执行,失败则可能再次 park
注意:AQS 不是简单地“park 后等 unpark”,而是结合 volatile 状态、CAS 和循环检测,确保线程安全地等待与响应。
使用 LockSupport 的注意事项
直接使用 LockSupport 编写同步逻辑极易出错,仅建议用于学习或极简场景。实际开发中应优先使用高级并发工具。若必须手动使用,请牢记:
- park/unpark 不可重入:多次 unpark 只保留一个 permit(即 permit 最大为 1)
- 务必在 park 前检查退出条件(如用 while 循环包裹 park),防止虚假唤醒导致逻辑错误
- 避免在未持有锁的情况下裸调 park,否则无法保证状态可见性(需配合 volatile 或原子变量)
- park 会响应中断,但不会抛出 InterruptedException,需手动检查
Thread.interrupted()
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











