JUC并发编程:LockSupport.park() 与 unpark() 深度解析

一、前言

在Java并发编程中,AQS (AbstractQueuedSynchronizer) 是实现锁(如 ReentrantLock)、同步器(如 CountDownLatch)的核心基础。而 AQS 能够实现线程的阻塞与唤醒,其底层完全依赖于LockSupport工具类。

LockSupport 是 JUC 包中的一个工具类,主要用于挂起(block)和唤醒(wake up)线程。它所有的方法都是静态的,底层通过Unsafe类实现。


二、基本使用

LockSupport 主要是通过 park() 和 unpark(Thread thread) 来实现的。

  • park(): 阻塞当前线程,直到获得“许可”或被中断。

  • unpark(Thread thread): 给指定线程发放一个“许可”,如果该线程被阻塞,则将其唤醒。

1. 标准用法:先 park 后 unpark

这是最直观的用法,主线程让子线程阻塞,然后三秒后唤醒它。

import java.util.concurrent.locks.LockSupport; public class ParkUnparkDemo { public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(() -> { System.out.println(Thread.currentThread().getName() + " --- 1. 开始运行"); // 阻塞当前线程 LockSupport.park(); System.out.println(Thread.currentThread().getName() + " --- 3. 被唤醒"); }, "t1"); t1.start(); // 睡眠3秒,确保t1先执行并进入park状态 Thread.sleep(3000); System.out.println(Thread.currentThread().getName() + " --- 2. 发起唤醒"); // 唤醒线程t1 LockSupport.unpark(t1); } }

运行结果:

codeText

t1 --- 1. 开始运行 main --- 2. 发起唤醒 t1 --- 3. 被唤醒

2. 特殊用法:先 unpark 后 park

这是 LockSupport 与 Object.wait() 最大的区别之一。
即使 unpark 操作发生在 park 之前,线程依然可以正常通过(不会永久阻塞)。

import java.util.concurrent.locks.LockSupport; public class UnparkFirstDemo { public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(() -> { try { // 让子线程睡一会儿,保证主线程先执行 unpark Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " --- 2. 准备park"); // 因为之前已经有许可了,这里不会阻塞,直接通过 LockSupport.park(); System.out.println(Thread.currentThread().getName() + " --- 3. park结束,继续执行"); }, "t1"); t1.start(); System.out.println(Thread.currentThread().getName() + " --- 1. 提前发放许可"); // 提前给t1线程发放许可 LockSupport.unpark(t1); } }

原理简述:unpark 就像是给线程的钱包里预存了一张票,等线程执行 park 需要买票进站时,发现钱包里已经有票了,直接刷票进站,无需等待。


三、与 Object.wait/notify 的区别(重点)

在面试和实际开发中,这两组机制经常被拿来对比:

特性Object.wait() / notify()LockSupport.park() / unpark()
所属对象Object 类的方法LockSupport 类的静态方法
锁的要求必须在 synchronized 代码块中执行,否则抛 IllegalMonitorStateException不需要获取任何锁,随时随地可调用
锁的释放执行 wait 会释放当前持有的锁执行 park不会释放当前持有的锁(容易死锁,需注意)
执行顺序必须先 wait 后 notify。如果先 notify 后 wait,线程会永久等待顺序无关。可以先 unpark 存入许可,后 park 消费许可
中断响应抛出 InterruptedException 异常不抛异常,park 方法直接返回,需要通过 Thread.interrupted() 检查状态

四、底层原理深度解析

LockSupport 的底层是一个 native 方法,最终调用的是 JVM 内部(C++实现)的 Parker 对象。核心理念是"Permit"(许可)

1. Permit (许可) 机制

我们可以将 Permit 理解为一个二元信号量(0 或 1),它不累加

  • park() 流程:

    1. 检查当前线程是否有许可(Permit)。

    2. 如果有(Permit = 1):消耗许可(Permit 变为 0),park 方法立即返回,线程继续运行。

    3. 如果没有(Permit = 0):阻塞当前线程,直到被唤醒。

  • unpark(Thread t) 流程:

    1. 将指定线程的许可设置为 1(Permit 变为 1)。

    2. 注意:因为是二元信号量,多次调用 unpark 不会叠加。unpark 100次,Permit 依然是 1。此时调用一次 park 就会消耗掉这个许可,第二次调用 park 依然会阻塞。

2. 源码级验证 (HotSpot VM)

在 JVM 源码(os_linux.cpp 和 os_windows.cpp 等)中,每个 Java 线程都有一个对应的 C++ 类 Parker 实例。

Parker 类主要包含三个核心变量:

  1. _counter: 记录许可数量(0 或 1)。

  2. _mutex: 互斥锁(用于保护操作)。

  3. _cond: 条件变量(用于线程挂起)。

Java底层图示:

C++ 伪代码逻辑演示

park() 的大致逻辑:

void Parker::park(bool isAbsolute, jlong time) { // 1. 如果已有许可(_counter > 0),直接消耗许可并返回 if (_counter > 0) { _counter = 0; return; } // 2. 获取互斥锁 pthread_mutex_lock(_mutex); // 3. 再次检查许可(防止并发情况) if (_counter > 0) { _counter = 0; pthread_mutex_unlock(_mutex); return; } // 4. 真正阻塞,等待信号(类似Java的wait) // 这里会释放锁并等待,直到被unpark唤醒或中断 pthread_cond_wait(_cond, _mutex); // 5. 唤醒后,将许可归零 _counter = 0; pthread_mutex_unlock(_mutex); }

unpark() 的大致逻辑:

void Parker::unpark(Thread* thread) { // 1. 获取互斥锁 pthread_mutex_lock(_mutex); // 2. 只有当许可为0时,才设置为1(不可累加) // 但无论之前是多少,最终状态都是1 int s = _counter; _counter = 1; // 3. 如果线程之前是阻塞状态(s < 1),唤醒它 if (s < 1) { // 发送信号唤醒在 _cond 上等待的线程 pthread_cond_signal(_cond); } pthread_mutex_unlock(_mutex); }

五、常见面试题与坑

1. 为什么推荐使用 park(Object blocker)?

在 Java 6 之后,LockSupport 新增了 park(Object blocker) 方法。

  • blocker 是用来标识当前线程在等待什么对象(通常传入 this)。

  • 作用:当使用 jstack 或 Profiler 工具排查死锁或性能问题时,能够显示出线程是被哪个对象 block 住的,极大地方便了问题定位。

对比:

  • park() 在 dump 文件中显示:parking to wait for <0x0000000000000000> (无信息)

  • park(this) 在 dump 文件中显示:parking to wait for <0x000000076b3820f0> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)

2. 中断(Interrupt)能唤醒 park 吗?

能。
当一个线程被 park 阻塞时,如果其他线程调用了该线程的 interrupt() 方法,park 会立即返回。
注意:不会抛出 InterruptedException,你需要手动检查中断标志位。

Thread t1 = new Thread(() -> { LockSupport.park(); // 这里的代码会在 unpark 或 interrupt 后执行 if (Thread.currentThread().isInterrupted()) { System.out.println("被中断唤醒了"); } }); t1.start(); t1.interrupt(); // 线程会立刻从 park 中醒来

3. 多次 unpark,能否抵消多次 park?

不能。

LockSupport.unpark(Thread.currentThread()); LockSupport.unpark(Thread.currentThread()); // 此时 permit 还是 1 LockSupport.park(); // 消耗 permit (1 -> 0),通过 LockSupport.park(); // permit 为 0,阻塞!

六、总结

  1. LockSupport 是 JUC 并发包的基石,AQS 依靠它来挂起和唤醒线程。

  2. 它利用Permit(许可)机制,解耦了阻塞和唤醒的顺序限制(可以先唤醒后阻塞)。

  3. 它底层利用操作系统的 Mutex 和 Condition Variable 实现,轻量且高效。

  4. 在使用时,要注意它不释放锁的特性,避免造成死锁。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1174800.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AIGC检测原理解析:为什么自己写的论文也会被判AI生成 - 还在做实验的师兄

AIGC检测系统识别的是「AI特征」而非「是否由AI生成」。规范的学术写作特征与AI特征高度重合,所以自己写的论文也可能被误判。解决方法是用嘎嘎降AI等专业工具处理,让文本「看起来更像人写的」。AIGC检测原理解析:为…

高校志愿服务管理系统-计算机毕业设计源码+无LW文档

摘要&#xff1a;本文旨在探讨高校志愿服务管理系统的开发与实施。通过分析当前高校志愿服务管理的现状和存在的问题&#xff0c;提出了开发一个综合性的志愿服务管理系统的需求。本文详细阐述了系统的需求分析、功能设计以及预期的社会和经济影响&#xff0c;旨在提高高校志愿…

论文AI率从90%降到5%,我用了这个方法 - 还在做实验的师兄

AI率90%是极高的情况,但专业工具可以处理。我用嘎嘎降AI把90%的AI率降到了5%以下,花了不到50块钱,全程20分钟。手动改根本不可能,直接用工具是唯一出路。论文AI率从90%降到5%,我用了这个方法TL;DR:AI率90%是极高…

2026年便宜好用的降AI工具推荐,学生党必看 - 还在做实验的师兄

学生党预算有限,推荐嘎嘎降AI(4.8元/千字,1000字免费试用)和率零(3.2元/千字,最便宜)。效果要求高选嘎嘎,纯省钱选率零。都有免费额度,先试再买。2026年便宜好用的降AI工具推荐,学生党必看TL;DR:学生党预算…

2026年降AI工具年度盘点:哪款最值得用 - 还在做实验的师兄

2026年降AI工具年度盘点:性价比之王是嘎嘎降AI(4.8元/千字,达标率99.26%),效果极致是比话降AI(8元/千字,可降至0%),最便宜是率零(3.2元/千字)。按需选择即可。2026年降AI工具年度盘点:哪款最值得用TL;DR:…

完整教程:Fresha 的实时分析进化:从 Postgres 和 Snowflake 走向 StarRocks

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

论文AI率从100%降到10%以下,我用的这几款工具 - 还在做实验的师兄

论文AI率太高别慌,用对工具完全能救回来。实测了十几款降AI工具,最终推荐嘎嘎降AI(99.5%→3.1%,性价比高)和比话降AI(可降至0%,知网专精)。手动改反而可能越改越高,别踩坑。论文AI率从100%降到10%以下,我用的…

强烈安利8个一键生成论文工具,专科生毕业论文轻松搞定!

强烈安利8个一键生成论文工具&#xff0c;专科生毕业论文轻松搞定&#xff01; AI 工具如何改变论文写作的未来 在当前的学术环境中&#xff0c;越来越多的专科生开始借助 AI 工具来提升论文写作的效率。尤其是那些对写作技巧不够熟悉、时间紧迫的学生&#xff0c;AI 工具的出现…

知网AIGC检测率太高?这5款降AI工具亲测有效 - 还在做实验的师兄

知网AIGC检测系统2025年12月升级后,检测逻辑从文本重合度转向语义连贯性分析,传统同义词替换彻底失效。亲测5款降AI工具后,推荐嘎嘎降AI(达标率99.26%,价格实惠)和比话降AI(专攻知网,不达标退款)。知网AIGC检…

研究生论文降AI率,导师推荐的3款工具 - 还在做实验的师兄

研究生论文AI率太高会影响评审和答辩。导师推荐嘎嘎降AI(达标率99.26%,4.8元/千字)、比话降AI(知网专精,8元/千字)处理。硬改效果差,专业工具更靠谱。研究生论文降AI率,导师推荐的3款工具TL;DR:研究生论文AI率…

深度测评继续教育AI论文写作软件TOP8:开题报告文献综述全攻略

深度测评继续教育AI论文写作软件TOP8&#xff1a;开题报告文献综述全攻略 2026年继续教育AI论文写作工具测评&#xff1a;精准匹配学术需求 随着人工智能技术的不断进步&#xff0c;AI论文写作工具在继续教育领域中的应用日益广泛。然而&#xff0c;面对市场上种类繁多的工具&a…

13.3 大规模仿真与数据驱动技能学习:以NVIDIA Isaac Gym为平台的高通量训练范式

13.3 大规模仿真与数据驱动技能学习:以NVIDIA Isaac Gym为平台的高通量训练范式 13.3.1 引言:数据驱动时代的技能获取瓶颈 在具身智能与物理AI的框架下,机器人需要通过大量与环境的交互来获取和优化技能,尤其是基于强化学习等数据驱动的方法。然而,直接在物理实体上进行…

多线程与并发-知识总结2

一、ThreadLocal1、什么是ThreadLocal&#xff1f;ThreadLocal是JDK包提供的&#xff0c;它提供了线程本地变量&#xff0c;如果你创建了一个ThreadLocal变量&#xff0c;那么访问这个变量的每个线程都会有这个变量的一个本地副本。当多个线程操作这个变量时&#xff0c;实际操…

12.2 动态行走与平衡控制:基于预测与鲁棒性原理的稳定步态生成

12.2 动态行走与平衡控制:基于预测与鲁棒性原理的稳定步态生成 12.2.1 引言:从静态平衡到动态行走的范式演进 人形机器人的行走问题被公认为是机器人学中最具挑战性的任务之一。早期的人形机器人多采用“静态行走”策略,其核心是通过精心规划足部轨迹,确保机器人的零力矩…

课程论文被查出AI率太高?这几款工具能救急 - 还在做实验的师兄

课程论文AI率要求通常比毕业论文宽松(30%以下),用嘎嘎降AI(4.8元/千字)或率零(3.2元/千字)处理即可。预算有限选率零,追求稳定选嘎嘎。课程论文被查出AI率太高?这几款工具能救急TL;DR:课程论文AI率要求通常比…

12.3 软硬件协同设计:从“大小脑”架构透视人形机器人的异构计算革命

12.3 软硬件协同设计:从“大小脑”架构透视人形机器人的异构计算革命 12.3.1 引言:人形机器人计算范式的瓶颈与演进 人形机器人的智能化依赖于一个复杂的计算闭环:高维传感器数据的实时感知(如多目视觉、激光雷达、IMU)、毫秒级的世界模型更新与决策(如状态估计、运动规…

13.1 具身智能的内涵与框架:物理实践、世界模型与感知-动作闭环

13.1 具身智能的内涵与框架:物理实践、世界模型与感知-动作闭环 13.1.1 引言:从“离身智能”到“具身智能”的范式迁移 自人工智能诞生之初,“智能”的载体长期被视为一个抽象的、符号处理的逻辑系统。这种**“离身智能”**的经典范式,根植于“物理符号系统假说”,其核心…

豆包、Kimi生成的内容如何通过AIGC检测?工具推荐 - 还在做实验的师兄

用豆包、Kimi等通用AI自己降AI率是行不通的(测试显示AI率反而会越改越高)。想让这些AI生成的内容通过AIGC检测,需要用专业降AI工具:嘎嘎降AI性价比高,比话降AI效果更彻底。豆包、Kimi生成的内容如何通过AIGC检测?…

基于Java的家电清洗智慧管理系统的设计与实现全方位解析:附毕设论文+源代码

1. 为什么这个毕设项目值得你 pick ? 家电清洗智慧管理系统结合了现代管理理念和技术手段&#xff0c;旨在提升家电清洗行业的运营效率和服务质量。系统功能模块化设计使其易于理解和操作&#xff0c;特别适合初次接触此类项目的开发者和学生使用。与传统选题相比&#xff0c…