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

RandLA-Net复现SemanticKITTI和S3DIS数据集 RandLA-Net复现KITTI和室内数据集 阅读详情

在上篇博客(【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的基本使用,以及对线程中断的响应性

Vue3 - 详解实现网站接入微信扫码登录功能,微信授权生成登录二维码用户用手机扫描二维码登陆,微信扫描二维码登录详细流程及示例代码,支持弹框式、浏览器单独新开页显示,最新vue集成微信扫码授权登录! vue3,nuxt3,PC网站,网页,微信扫码登录,微信登陆,vue3微信扫码登录,获取个人信息,扫码登录后如何获取用户手机号,微信扫码授权登录,vue3详细实现微信扫一扫登陆,pc网页微信登录,vue3集成微信扫码登录,详细流程和示例源码,第三方扫码登录,vue3微信扫码登录怎么新开一页,跳页显示二维码,内嵌登录二维码,iframe,iframe新页面弹出,弹出一个小窗口显示登录二维码,登录报错,微信扫码没反应,解决手机点登录报错没反应,官方文档,手机扫描微信二维码登录网站,最好用的插件,vue-wxlo 阅读详情

相关推荐

UDS(三)网络层时间参数

网络层定义了N_Ar、N_As、N_Br、N_Bs、N_Cr、N_Cs六个时间参数。 网络层在检测到错误的时间传递至上层使用者 1.当N_As 超时时,即发送方没有及时发送出N_PDU,系统将放弃信息的接收并传递<N_Result> = <N_TIMEOUT_A>的N_USData.comfirm指示 2.当N_Ar超时时,即接收方没有及时发送出N_PDU,系统将放弃信息的接收并传递<N_Result> = <N_TIMEOUT_A>的N_USData.co

weixin_44522306的博客 1万+

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

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

chenssy 的技术博客 1万+

PyMySQLSaver实战:构建高可靠性的LangGraph状态管理

本文详细介绍了如何使用PyMySQLSaver构建高可靠性的LangGraph状态管理系统。通过检查点机制和MySQL持久化技术,开发者可以确保AI应用在崩溃后从最近状态恢复,支持长时间运行任务和多轮交互。文章包含核心架构解析、生产环境部署指南及实战案例,帮助开发者掌握状态管理的核心技术。

weixin_29310605的博客 494

从源码来理解AQS

嘻嘻

Ccc_2018 279

ESP8266 进行HDLC解码,AX.25,APRS

/************************************************************** 函数名:aprs_wait_begin() 参 数:无 返回值:bool true=得到合法脉冲,false=未得到 说 明:等待第1个833us高脉冲,判断范围 730-930,其他忽略 ***************************************************************/ bool aprs_wait_begin(){ stati

蓝蓝的博客 1628

Vivado IP核与License许可全解析:从免费到收费,从评估到部署

本文全面解析Vivado IP核与License许可机制,从免费到收费IP核的选型指南到License的申请与部署策略。详细介绍了Xilinx官方IP核的优势与局限,第三方IP核的风险与应对,以及实战中的资源优化技巧和版本兼容性问题,帮助开发者高效利用Vivado工具链。

weixin_29169505的博客 367

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

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

qq_39108894的博客 1388

S32的进阶之路->3,S32DS新建/删除/导入工程

右击工程名,点击Delect进行工程删除。选中Delect project contents on disk则会彻底删除工程,不选中Delect project contents on disk工程文件会保存在工作空间中。在Improt Projects中选择工程所在文件夹,选中所需要导入的工程,勾选Copy projects into workspace。选中目标示例工程,点击Finish,完成创建工程。导入已有工程,右击右击Project Explorer空白处,选择Import。

LC_8575的博客 2224

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

jiayibingdong的博客 2668

新代永久解锁西门子smart S7-200PLC 上传程序步骤

西门子 SMART S7-200 PLC 程序上传步骤 打开编程软件 或左下角依次打开 程序 所有程序 Siemens Automation Simatic STEP 7-MicroWIN SMART V2.4 STEP 7-MicroWIN SMART 技术交流 plcjiesuo1 2. 确认plc电源端以及输入电压; 3.用网线连接plc与电脑技术交流 plcjiesuo1 4.plc通电; 5.打开编程软件,双击通讯 6.按照...

m0_60773720的博客 2万+

lammps 案例in文件汇总

进阶案例: 聚乙烯和石墨烯界面pull out模拟代码 反应力场reax/c设置方法及案例解析 石墨烯热导率模拟代码(NEMD方法) 圆锥形SiC纳米磨削单晶硅源代码 高熵合金FeNiCrCoCu纳米压痕模拟代码 fix indent命令实现纳米摩擦及摩擦力计算 Fe原子辐照轰击多层石墨烯模拟代码 铝基石墨烯复合物压缩变形in文件源代码 石墨烯自动卷曲到Fe纳米线模拟源代码 铝/石墨烯复合物结晶过程lammps模

lammps_jiayou的博客 9445

LockSupport实现原理

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

大模型训练 191

华为OD面试八股真题 - 操作系统 - 1

华为OD技术面,操作系统相关八股真题提供详细解答,这篇博客主要涉及于进程和线程相关知识点

qq_45776114的博客 1634

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

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

zdy0_2004的专栏 584

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

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

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

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

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

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

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

yanghan1222的博客 3923

WINCC7.3破解文件

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

从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、付费专栏及课程。

余额充值