如何深入理解并掌握LockSupport的原理?
摘要:本文会先梳理 LockSupport 的核心原理,再逐一对比它与 synchronized、Thread.sleep()、Object.wait()、Condition.await() 的区别,同时解答 notify()unpark()
本文会先梳理 LockSupport 的核心原理,再逐一对比它与 synchronized、Thread.sleep()、Object.wait()、Condition.await() 的区别,同时解答 notify()/unpark() 提前调用的关键问题,帮你彻底理清 Java 并发中线程阻塞/唤醒的核心逻辑。
一、LockSupport 核心原理回顾
LockSupport 是 JDK 并发包的底层工具类,核心是许可(Permit)机制:
每个线程绑定一个「许可」,许可只有两种状态:可用(1)、不可用(0),且最多只能有 1 个许可(不可累加);
park():尝试获取许可,获取到则消耗许可(变为 0)并直接返回;获取不到则阻塞线程,直到被唤醒/中断/超时;
unpark(Thread t):为线程 t 发放许可(若已存在则无效果),若线程正阻塞在 park() 上则唤醒它;
底层依赖 sun.misc.Unsafe 调用 JVM 的 Parker 类,最终通过操作系统的 futex 系统调用实现线程挂起/唤醒。
二、各类同步方法的核心区别对比
1. LockSupport vs synchronized
维度
LockSupport
synchronized
核心作用
线程阻塞/唤醒的底层工具
实现方法/代码块的互斥与同步
底层实现
Unsafe + Parker + 操作系统 futex
偏向锁→轻量级锁→重量级锁(监视器锁)
使用方式
静态方法直接调用(park/unpark)
修饰方法/代码块(隐式获取/释放锁)
阻塞/唤醒粒度
精准唤醒指定线程(unpark(Thread t))
随机唤醒一个(notify())/全部(notifyAll())
前置条件
无需持有任何锁
必须先获取对象的监视器锁
中断响应
响应中断,返回后需手动检查中断状态
响应中断,抛出 InterruptedException
灵活性
极高(支持超时、先unpark后park安全)
较低(锁释放仅在代码块结束/异常时)
核心差异:synchronized 是「锁」,侧重资源互斥;LockSupport 是「线程控制工具」,是实现锁的基础。比如 ReentrantLock 内部就是通过 AQS 调用 LockSupport 实现线程阻塞。
