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

LockSupport从入门到深入理解 LockSupport Condition ,wait,notify 阅读详情

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

lock方法,在调用acquireQueued():

[java]  view plain  copy
  1. if (shouldParkAfterFailedAcquire(p, node) &&  
  2.                     parkAndCheckInterrupt())  
  3.                     interrupted = true;  

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

[java]  view plain  copy
  1. private final boolean parkAndCheckInterrupt() {  
  2.         LockSupport.park(this);  
  3.         return Thread.interrupted();  
  4.     }  

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

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

[java]  view plain  copy
  1. public final boolean release(int arg) {  
  2.         if (tryRelease(arg)) {  
  3.             Node h = head;  
  4.             if (h != null && h.waitStatus != 0)  
  5.                 unparkSuccessor(h);  
  6.             return true;  
  7.         }  
  8.         return false;  
  9.     }  

在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;或者
  • 其他某个线程中断当前线程;或者
  • 该调用不合逻辑地(即毫无理由地)返回。

    其源码实现如下:

    [java]  view plain  copy
    1. public static void park() {  
    2.         unsafe.park(false, 0L);  
    3.     }  

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

    其源代码如下:

    [java]  view plain  copy
    1. public static void unpark(Thread thread) {  
    2.         if (thread != null) {   
    3.             Object lock = unsafe.getObject(thread, lockOffset);  
    4.             synchronized (lock) {   
    5.                 if (thread.isAlive()) {   
    6.                     unsafe.unpark(thread);   
    7.                 }   
    8.             }   
    9.         }   
    10.     }  

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

     

    参考资料

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

LockSupport与Condition解析 剖析了Java并发包中的两个核心线程协作工具:LockSupport和Condition。LockSupport基于Unsafe类提供底层的线程阻塞(park)和唤醒(unpark)机制,支持精确线程唤醒。Condition作为更强大的wait/notify替代方案,与Lock配合使用,具有独立等待队列、灵活唤醒方式和超时机制等优势。重点分析了ConditionObject的await方法实现,包括节点加入条件队列、锁释放、线程阻塞及唤醒后的锁竞争流程,并通过生产者-消费者模型展示了Conditi 阅读详情

相关推荐

用AI+Playwright实现零代码UI自动化测试:以登录页面为例的实战指南

本文详细介绍了如何利用AI与Playwright结合实现零代码UI自动化测试,特别以登录页面为例进行实战演示。通过自然语言描述生成测试脚本,大幅降低技术门槛,提升测试效率,并支持跨浏览器验证。适合非技术人员快速上手专业级自动化测试。

weixin_28842269的博客 401

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

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

chenssy 的技术博客 1万+

手把手教你用STM32F103的GPIO模拟MIPI RFFE协议(附完整代码与逻辑分析仪调试技巧)

本文详细解析了如何使用STM32F103的GPIO模拟MIPI RFFE协议,包括协议核心、硬件准备、时序模拟、寄存器操作及逻辑分析仪调试技巧。通过实战代码和波形分析,帮助工程师解决电平转换、奇校验处理等常见问题,提升通信稳定性与效率。

weixin_30292745的博客 284

从源码来理解AQS

嘻嘻

Ccc_2018 279

高等数学/概率论/数理统计/线性代数/离散数学面试-核心概念-问题理解

特征值与特征向量是线性代数中的概念,它们与线性变换有关。在线性变换中,如果存在非零向量 v ,使得当该向量通过变换后,其方向不变,只是长度发生了变化,那么这个向量 v 就是特征向量。而这个长度变化的比例因子,即变换前后向量长度的比值,称为特征值。数学公式表示:通俗易懂的解释:想象一下,你有一个可以伸缩的橡皮筋,这个橡皮筋可以代表一个向量。现在,你有一个特殊的机器,它可以改变橡皮筋的形状,但不会改变它延伸的方向。当你把橡皮筋放入机器中,机器会拉伸或压缩橡皮筋,但橡皮筋的方向保持不变。

m0_64198455的博客 2292

深入理解 DDR5 Bank Group 与并行调度机制

Bank Group架构和并行调度机制,是DDR5性能跃升的核心秘密!理解它们才能写出高效调度程序,设计出性能强劲又稳定的DDR5系统。🎯记住:Bank Group不是简单的分组,而是高速并行的“魔法钥匙”,巧用它,你的DDR5设计将爆发惊人性能!

weixin_43199439的博客 312

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

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

qq_39108894的博客 1388

rk3568 修改开机动画

bootanimation.zip是一个Android设备启动时播放的动画文件,它包含了一系列的图片和描述文件,用于描述动画的播放顺序和持续时间。

weixin_35723192的博客 2727

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

jiayibingdong的博客 2668

【异常】Hermes Agent调用z.ai接口失败(余额不足)API call failed (attempt 1/3): RateLimitError [HTTP 429]

补充说明:同步尝试解析接口对应网页时,出现“网页解析失败,可能是不支持的网页类型,请检查网页或稍后重试”提示,该提示不影响核心报错排查,仅作为辅助信息。

奶爸的编程之路,也就一周冷个三天 1193

搞定ESD(九):静电放电之PCB设计

不同信号参考地平面应尽量保持完整,减小静电电流流过参考地平面时造成的电位差,防止电位差导致的信号传输电平错误.主芯片GPIO信号布线应保持最短化,减小与参考地平面之间的电场耦合,同时也防止因信号环路面积较大耦合静电放电噪声干扰。外部端子接地引脚顶层采用分地设计,最好是直接过孔到完整参考地平面接地,避免与顶层信号包地、其它包地相连,防止顶层串扰耦合到其它信号,造成ESD问题。

记得诚 1950

并发编程之LockSupport的 park 方法及线程中断响应

并发编程之LockSupport的 park 方法及线程中断响应

yemuxiaweiliang的博客 3148

【Mode】微带传输线阻抗

微带线,英文名称为 (Microstrip) 是一种常见的平面传输线,主要用于传输微波频率信号(通常在射频和微波电路重中使用)。

u011699626的博客 243

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

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

zdy0_2004的专栏 584

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

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

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

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

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

大树叶 技术专栏 393

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

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

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

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

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

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

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

yanghan1222的博客 3922

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

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

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

使用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

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

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

Ramscy 6007

LockSupport详解

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

落日的博客 1793

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

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

做最亮的星星 3444

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

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

油墨香^-^的博客 662
上一篇: Java并发编程 AQS分析(二):获取锁、释放锁
下一篇: Java并发编程实战 AQS(四):CLH同步队列
大树叶
博客等级 码龄12年 1171粉丝 664原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值