Java并发编程实战----- AQS(三):阻塞、唤醒:LockSupport

灵魂三问:因果推断 什么是因果推断?为什么研究因果推断?怎么进行因果推断研究? 阅读详情

在上篇博客(【Java并发编程实战】----- AQS(二):获取锁、释放锁)中提到,当一个线程加入到CLH队列中时,如果不是头节点是需要判断该节点是否需要挂起;在释放锁后,需要唤醒该线程的继任节点

lock方法,在调用acquireQueued():

if (shouldParkAfterFailedAcquire(p, node) &&
                    parkAndCheckInterrupt())
                    interrupted = true;

在acquireQueued()中调用parkAndCheckInterrupt()来挂起当前线程:

private final boolean parkAndCheckInterrupt() {
        LockSupport.park(this);
        return Thread.interrupted();
    }

调用LockSupport.park()方法。对于park():为了线程调度,在许可可用之前禁用当前线程。

释放锁后,需要唤醒该线程继任节点:

复制代码
public final boolean release(int arg) {
        if (tryRelease(arg)) {
            Node h = head;
            if (h != null && h.waitStatus != 0)
                unparkSuccessor(h);
            return true;
        }
        return false;
    }
复制代码

在release方法中调用unparkSuccessor()来唤醒该线程的继任节点。在unparkSuccessor()方法中通过LockSupport.unpark()来唤醒。unpark():如果给定线程的许可尚不可用,则使其可用。

LockSupport

LockSupport是用来创建锁和其他同步类的基本线程阻塞原语。每个使用LockSupport的线程都会与一个许可关联,如果该许可可用,并且可在进程中使用,则调用park()将会立即返回,否则可能阻塞。如果许可尚不可用,则可以调用 unpark 使其可用。但是注意许可不可重入,也就是说只能调用一次park()方法,否则会一直阻塞。

LockSupport.park()、LockSupport.unpark()的作用分别是阻塞线程和解除阻塞线程,且park()和unpark()不会遇到“Thread.suspend ()和 Thread.resume所可能引发的死锁”问题。当然park()、unpark()是成对使用。

park():如果许可可用,则使用该许可,并且该调用立即返回;否则,为线程调度禁用当前线程,并在发生以下三种情况之一以前,使其处于休眠状态:

  • 其他某个线程将当前线程作为目标调用 unpark;或者
  • 其他某个线程中断当前线程;或者
  • 该调用不合逻辑地(即毫无理由地)返回。

    其源码实现如下:

    public static void park() {
            unsafe.park(false, 0L);
        }

    unpark:如果给定线程的许可尚不可用,则使其可用。如果线程在 park 上受阻塞,则它将解除其阻塞状态。否则,保证下一次调用 park 不会受阻塞。如果给定线程尚未启动,则无法保证此操作有任何效果。

    其源代码如下:

    复制代码
    public static void unpark(Thread thread) {
            if (thread != null) { 
                Object lock = unsafe.getObject(thread, lockOffset);
                synchronized (lock) { 
                    if (thread.isAlive()) { 
                        unsafe.unpark(thread); 
                    } 
                } 
            } 
        }
    复制代码

     

    一般来说park()、unpark()是成对出现的,同时unpark必须要在park执行之后执行,当然并不是说没有不调用unpark线程就会一直阻塞,park有一个方法,它带了时间戳(parkNanos(long nanos):为了线程调度禁用当前线程,最多等待指定的等待时间,除非许可可用。)

     

    参考资料

    1、LockSupport的park和unpark的基本使用,以及对线程中断的响应性

因时机器人-灵巧手配置方案(Ubuntu18.04) 阅读详情

相关推荐

Trae IDE与Playwright MCP:5分钟实现零代码网页数据抓取

网页数据抓取是数据采集和自动化处理中的基础技术,其核心原理是通过程序模拟浏览器行为,定位并提取页面中的结构化信息。传统方式依赖编写脚本处理网络请求、解析HTML和应对反爬机制,技术门槛较高。而结合AI与自动化工具的新范式,通过自然语言交互即可完成复杂操作,极大降低了技术门槛并提升了开发效率。这种技术价值在于将开发者从繁琐的编码中解放,使其更专注于数据分析和业务逻辑。在数据监控、市场调研、竞品分析等应用场景中,快速获取网页数据是关键需求。本文以Trae IDE集成Playwright MCP为例,演示如何通过

culi3118的博客 498

【Java并发编程实战】—– AQS(三):阻塞、唤醒:LockSupport

在上篇博客(【Java并发编程实战】—– AQS(二):获取锁、释放锁)中提到,当一个线程加入到CLH队列中时,如果不是头节点是需要判断该节点是否需要挂起;在释放锁后,需要唤醒该线程的继任节点lock方法,在调用acquireQueued():if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckI

chenssy 的技术博客 1万+

Flink CDC 1.18.1 Oracle 数据同步到postgresql

8、修改Flink的配置文件,主要是各种服务的绑定地址,默认为localhost,统统改为0.0.0.0,如:rest.address: 0.0.0.0 #localhost。将flink-sql-connector-oracle-cdc-3.0.1.jar复制到flink-1.18.1/lib目录中。6、下载 flink-connector-jdbc-3.1.1-1.17.jar,postgresql-42.7.3.jar。7、安装postgresql就不说了,相信你已经有了数据库了。

ynzhangyao的专栏 1799

从源码来理解AQS

嘻嘻

Ccc_2018 279

高通平台camera构架sensor驱动详解

优先阅读。

a5566255的专栏 3251

PCL RANSAC拟合分割多条直线【2026最新版】

使用RANSAC算法拟合分割多条直线,输出每一条直线的拟合参数到控制台,并保存直线点云到本地文件夹。博客长期更新,本文最新更新时间为:2026年5月24日。

点云侠的博客 7974

Java源码学习之高并发编程基础——AQS源码剖析之阻塞队列(上)

AQS的核心源码解读——以独占锁的例子进行AQS最重要的两个功能:等锁节点的入队、等锁节点获取到锁以后的出队。

qq_39108894的博客 1388

Qt入门教程【基础控件篇】QLineEdit输入框

QLineEdit输入框

小鱼酱的博客 3261

java多线程进阶(四)LOCK锁及其原理

jiayibingdong的博客 2668

华为OD机试真题 2026-9-2【查找幸运数】

华为OD机试真题 新系统【查找幸运数】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题 【查找幸运数】多语言题解。

qq_45776114的博客 497

DeepSeek掘金——用DeepSeek模型构建AI 代理

在本综合指南中,我们将探讨如何利用 DeepSeek 的功能构建能够以有意义的方式理解、推理和交互的复杂 AI 代理。人工智能领域正在迅速发展,DeepSeek 的模型代表了智能 AI 代理开发的重大进步。在本综合指南中,我们将探讨如何利用 DeepSeek 的功能构建能够以有意义的方式理解、推理和交互的复杂 AI 代理。

3858

LockSupport实现原理

前文中了解到AQS借助LockSupport.park和LockSupport.unpark完成线程的阻塞和唤醒,那么LockSupport内部又是怎么实现的?这是一个什么类?

大模型训练 191

项目管理 Agent:进度追踪与风险预警 Harness

我们先从LangChain的Agent定义说起:Agent是一个能感知环境、自主决策、调用工具、执行动作、迭代反思的智能实体。而「项目管理全自主Agent」,就是把Agent的核心能力和项目管理的五大过程组(启动、规划、执行、监控、收尾)深度结合,聚焦执行监控阶段的两个核心痛点:进度偏差自动化计算、风险信号自动化识别与预警的专门化Agent。全感知(Omnisensing):能从。

AI架构师小马 515

【Java并发编程实战】----- AQS(三):阻塞、唤醒:LockSupport

http://www.cnblogs.com/chenssy/p/5079724.html 在上篇博客(【Java并发编程实战】----- AQS(二):获取锁、释放锁)中提到,当一个线程加入到CLH队列中时,如果不是头节点是需要判断该节点是否需要挂起;在释放锁后,需要唤醒该线程的继任节点 lock方法,在调用acquireQueued(): if (shouldPa

zdy0_2004的专栏 584

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

LockSupport详解:Java并发编程的基石

是用来创建锁和其他同步类的基本线程阻塞原语。它提供了一组静态方法,让线程可以阻塞(park)和唤醒(unpark)。阻塞方式锁释放使用位置唤醒方式适用场景不释放任意自动简单延时释放synchronized块notify线程间通信释放lock.lock()后signal高级锁不释放任意unpark底层工具知识点一句话总结核心功能线程阻塞(park)和唤醒(unpark)的基本原语底层实现基于Unsafe的park/unpark native方法许可机制。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 3112

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Java中的AQS(三)线程的阻塞和唤醒

一、线程的阻塞:        在上一篇说到,线程获取同步状态失败的线程,会构造节点并加入到同步队列的尾部,然后通过自旋的方式不断的获取同步状态,但是在自旋过程中需要判断线程是否需要阻塞,我们再一次看一下acquire方法。final boolean acquireQueued(final Node node, int arg) { boolean failed = true; t...

yanghan1222的博客 3923

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

从0到1带你深入并发编程003:AQS核心架构深度解析:同步状态、CLH队列与LockSupport

摘要:本文深度解析Java并发框架核心AQS(AbstractQueuedSynchronizer)的设计原理,重点剖析其三大核心组件:同步状态(state)管理、CLH队列算法和LockSupport线程调度机制。通过源码分析展示了AQS如何实现公平锁获取、线程排队和精确唤醒,并比较了其与传统同步机制的性能优势。文章还总结了AQS设计中的软件工程原则和实际开发中的性能优化建议,为理解Java并发底层机制提供了系统性视角。

源码获取 | 运行部署 | 定制二开修改,如果回复不及时请耐心等待,请见谅。 1534

使用LockSupport实现线程阻塞与唤醒:比wait/notify更灵活的控制

是Java并发包中的一个工具类,它提供了一组静态方法,用于阻塞和唤醒线程。它的核心功能是park和unpark。park()阻塞当前线程,除非获得许可证(permit)。如果调用park()时,线程已经持有许可证,则park()立即返回,并清除许可证。其他线程调用方法,将当前线程作为参数,并给予其许可证。当前线程被中断。发生“虚假唤醒”(spurious wakeup)。给予指定线程一个许可证。如果指定线程之前因为调用park()方法而被阻塞,那么它会被唤醒,并获得许可证,park()方法返回。

weixin_41455464的博客 910

【032】AQS 的 “手脚”:LockSupport 如何让线程 “听话排队”?

通过门禁系统的类比,解析了LockSupport与AQS的协作机制。当线程排队时,AQS通过LockSupport的park/unpark方法精准控制线程阻塞与唤醒,解决了wait/notify的局限性。关键特性包括:1)许可机制确保一次只唤醒一个线程;2)unpark可先于park执行,避免唤醒延迟问题。AQS的acquire方法源码展示了“抢锁-入队-阻塞”的全流程,而LockSupport的灵活调用正是AQS高效管理线程的核心。通过案例演示,揭示了线程排队和唤醒的底层原理。

编程技术圈 1216

LockSupport 源码深度解析:Java 并发编程的底层基石

在Java并发编程中,是一个极其重要的工具类,它提供了线程阻塞和唤醒的基础能力。作为Semaphore等并发工具类的底层支撑,是Java并发框架的基石之一。本文将深入解析的源码实现,揭示其背后的原理和设计思想,帮助你更好地理解和应用Java并发编程。作为Java并发编程的底层基石,其设计简洁而高效,通过许可证机制实现了线程的精确阻塞和唤醒。通过深入理解的源码实现,我们可以更好地掌握Java并发编程的核心机制。关键总结:许可证机制。

喜欢炒股的码农 1007

LockSupport详解

LockSupport 是 Java 并发包(java.util.concurrent)中的一个工具类,提供了基本的线程阻塞和唤醒机制。它主要用于实现锁和其他同步类,如AQS、 ReentrantLock、Semaphore、CountDownLatch 等。LockSupport 提供的主要方法是park和unpark,它们分别用于挂起和唤醒线程(会让线程进入WATING状态)。AQS中对线程进行挂起和唤醒操作最终使用的就是和。AQS相关内容可以参考 我的上一篇博客AQS详解。

落日的博客 1793

Java线程阻塞和唤醒的几种方式

Object类自带的方法 使用wait()方法来阻塞线程,使用notify()和notifyAll()方法来唤醒线程。 调用wait()方法后,线程将被阻塞,wait()方法将会释放当前持有的监视器锁(monitor),直到有线程调用notify/notifyAll()方法后方能继续执行。 notify/notifyAll()方法只是解除了等待线程的阻塞,并不会马上释放监视器锁,而是在相应的被synchronized关键字修饰的同步方法或同步代码块执行结束后才自动释放锁。 默认使用非公平锁,无法修改。 缺点

Ramscy 6007

J.U.C 之 AQS:阻塞和唤醒线程详解

AQS(AbstractQueuedSynchronizer)是Java并发框架的核心组件,采用CLH队列变体管理等待线程。其核心机制包括:1)通过volatile int状态变量控制同步;2)使用CAS实现原子更新;3)基于LockSupport实现精准的线程阻塞(park)与唤醒(unpark)。AQS支持独占/共享两种模式,提供条件变量(ConditionObject)实现线程协作,并灵活处理中断请求。典型实现包括ReentrantLock等同步器,开发者也可基于AQS自定义锁。性能优化方面采用自旋策

油墨香^-^的博客 662

并发编程之——AQS原理和阻塞队列变化

1、AQS简介 2、源码分析 2.1 线程阻塞 2.2 线程唤醒 1、AQS简介 AQS全名:AbstractQueuedSynchronizer,它就是Java的一个抽象类,它的出现是为了解决多线程竞争共享资源而引发的安全问题,细致点说AQS具备一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是用CLH队列锁实现的,即将暂时获取不到锁的线程加入到队列中,队列是双向队列。 常用...

做最亮的星星 3444

Java LockSupport 工具类:线程阻塞 / 唤醒的底层原理(替代 wait/notify)

摘要:LockSupport是Java中更高效的线程协作工具,解决了wait/notify的三大痛点:无需同步锁、支持精准唤醒、避免信号丢失。其核心是许可机制,每个线程最多持有一张许可,park消耗许可,unpark发放许可。相比wait/notify,LockSupport更灵活可靠,被广泛用于并发框架底层。实际使用时需注意:1)一次park对应一次unpark;2)park后必须检查中断状态;3)确保线程引用有效;4)定时阻塞用parkNanos;5)避免多线程共享引用。正确使用LockSupport能

m0_67391377的博客 880

java并发编程(6)-AQS原理剖析

刚开始head节点和tail节点都是空的,在第一次循环时,我们将先对head节点和tail节点初始化为空Node,在第二次循环时才将当前Node入队,通过将tail节点设置为当前节点的前驱节点,并且CAS操作使自己成为新的tail节点(因为第一次CAS入队时的tail节点和head节点指向的是同一个对象,所以第一次入队实际上是将head节点设置为当前节点的前驱节点)。上面的就是AQS的类图,从类图中可以比较明显的看出,AQS是一个双向队列,并且队列中的元素是Node对象。enq的方法很简单,逻辑也很清晰。

2401_87704405的博客 1186
上一篇: Java Condition 的await(), singal(), singalAll() 具体代码实现分析,
下一篇: Java并发编程实战---- AQS(二):获取锁、释放锁
大树叶
博客等级 码龄12年 1171粉丝 664原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值