首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么`h`的参数会在AbstractQueuedSynchronizer中两次判断是否为空?

在AbstractQueuedSynchronizer(AQS)中,h参数的两次判断是否为空是为了确保在并发环境下,能够正确地处理线程的等待队列。

首先,需要了解AQS是Java中用于实现同步器的基础框架。它通过维护一个等待队列来管理线程的竞争和等待状态。在AQS中,每个等待线程都会被封装成一个Node节点,并加入到等待队列中。

在AQS的源码中,h参数代表了等待队列的头节点(head)。头节点是等待队列中的第一个节点,它的作用是标识当前持有锁的线程或者正在竞争锁的线程。

第一次判断是否为空是在acquireQueued方法中,用于判断等待队列是否为空。如果等待队列为空,说明当前没有线程在等待获取锁,可以直接返回。这样可以避免不必要的线程唤醒和竞争。

第二次判断是否为空是在doReleaseShared方法中,用于判断头节点的下一个节点是否为空。如果下一个节点为空,说明当前头节点是最后一个等待获取锁的节点,可以将头节点设置为null,释放锁资源。这样可以避免不必要的节点保留,减少内存占用。

综上所述,h参数在AbstractQueuedSynchronizer中两次判断是否为空是为了确保在并发环境下,能够正确地处理线程的等待队列。第一次判断用于判断等待队列是否为空,第二次判断用于判断头节点的下一个节点是否为空,以便正确地释放锁资源。

腾讯云相关产品和产品介绍链接地址:

  • 腾讯云云服务器(CVM):https://cloud.tencent.com/product/cvm
  • 腾讯云云数据库MySQL版:https://cloud.tencent.com/product/cdb_mysql
  • 腾讯云容器服务(TKE):https://cloud.tencent.com/product/tke
  • 腾讯云人工智能:https://cloud.tencent.com/product/ai
  • 腾讯云物联网平台:https://cloud.tencent.com/product/iotexplorer
  • 腾讯云移动开发平台:https://cloud.tencent.com/product/mpp
  • 腾讯云对象存储(COS):https://cloud.tencent.com/product/cos
  • 腾讯云区块链服务(BCS):https://cloud.tencent.com/product/bcs
  • 腾讯云虚拟专用网络(VPC):https://cloud.tencent.com/product/vpc
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

vue 对象判断_Vue可用判断对象是否方法

: StringUtils.isEmpty(CharSequence cs); //org.apache.commons.lang3包下StringUtils类,判断是否方法参数是字符序列类,也就是...Object.keys(xxx).length==0 验证结果如下:… 前言:在实现业务逻辑过程,很多工程师都会遇到需要判断一个对象,数组是否情景,很多时候我们在请求数据时候都需要判断请求对象数据是否...,如果直接使用,在数据请求时,控制台就会报错.因此我们需要给一个判断,如果数据存在就直接调用,不存在就创建对象/数组.下面狗尾草给大家整理了几种判断对象是否方法,希望对大家有帮助. 1.我们在需要请求对象.../数组下标或属性来判断是否 var oData = Obj.item !...,strFolderPath); if(AfxMessageBox(strMsg,MB_YESNO) == IDYES) { //… js判断字符是否方法: //判断字符是否方法 function

6.1K20
  • Django ORM判断查询结果是否,判断djangoorm实例

    print "QuerySet is empty" 总结: QuerySet.exists() QuerySet.count()==0 QuerySet 补充知识:关于在Sqlite3如何判断数据表返回结果集是否问题解决...shell可以看到该条查询语句在结果集时候确实返回了1行1列,不过那个行为空行。...在此种情况下,只能对返回结果集字符串指针(char **dbResult)判断是否来解决结果集是否问题,而不能以columnum和rownum是否0来判断。...//结果集不为。 ? 2、如果查询语句不只有聚合函数,”select * from tablename”,则可以对columnum和rownum判断0,来判断结果集是否。...以上这篇Django ORM判断查询结果是否,判断djangoorm实例就是小编分享给大家全部内容了,希望能给大家一个参考。

    6.9K10

    java判断一个对象是否_Java判断对象是否方法详解

    这两种StringUtils工具类判断对象是否是有差距: StringUtils.isEmpty(CharSequence cs); //org.apache.commons.lang3包下StringUtils...类,判断是否方法参数是字符序列类,也就是String类型 StringUtils.isEmpty(Object str); //而org.springframework.util包下参数是Object...接下来就是判断数组是否 list.isEmpty(); //返回boolean类型。...判断集合是否 例1: 判断集合是否: CollectionUtils.isEmpty(null): true CollectionUtils.isEmpty(new ArrayList()):...b)(A与B差): {1,2,3} CollectionUtils.subtract(b, a)(B与A差): {4,6,7} 以上所述是小编给大家介绍Java判断对象是否方法详解整合,希望对大家有所帮助

    3.2K20

    总结java判断对象是否方法「建议收藏」

    “java”判断对象是否方法有三种,分别是:一、根据“for...in”遍历对象,如果存在则返回“true”,否则返回“false”;二、利用“ES6”“Object.keys()”来进行判断...大家好,我是架构君,一个会写代码吟诗架构师。今天说一说总结java判断对象是否方法,希望能够帮助大家进步!!! 我们想要判断对象是否,像基本类型那样判断是不可以, ==={} ?...这样是错误,因为这只是比较引用地址是否相同,所以可以采取下面的方法来进行判断。...()来进行判断 (推荐) Object.keys()方法会返回一个由一个给定对象自身可枚举属性组成数组。...如果我们对象,他会返回一个数组。 Object.keys(obj).length === 0 ? '' : '不为' 更多感谢大家,希望帮助更多的人

    9.8K30

    死磕 java同步系列之ReentrantLock源码解析(一)——公平锁、非公平锁

    ,非公平锁在一开始就多了两次直接尝试获取锁过程。...h = head; // 如果头节点不为,且等待状态不是0,就唤醒下一个节点 // 还记得waitStatus吗?..., ws, 0); // 头节点下一个节点 Node s = node.next; // 如果下一个节点,或者其等待状态大于0(实际已取消) if (s == null...; 未完待续,下一章我们继续学习ReentrantLock关于条件锁部分 彩蛋 为什么ReentrantLock默认采用是非公平模式?...为什么非公平模式效率比较高? 答:因为非公平模式会在一开始就尝试两次获取锁,如果当时正好state0,它就会成功获取到锁,少了排队导致阻塞/唤醒过程,并且减少了线程频繁切换带来性能损耗。

    49430

    ReentrantLock是如何基于AQS实现

    而非公平锁实际实现方法nonfairTryAcquire。...再判断持有该锁线程是否当前线程,如果是当前线程就将state值加1,在释放锁是也需要释放多次。这就是可重入锁实现。 如果持有锁线程并非当前线程则这次加锁失败,返回false。...然后判断等待队列尾节点是否,如果不为则通过cas方式将当前节点接在队尾。如果tail则执行enq方法。...首先判断当前节点是否头结点下一个节点,如果是则再次调用tryAcquire尝试获取锁。当然这个过程并不是一定不停进行,这样的话多线程竞争下cpu切换也极耗费资源。...整个方法逻辑就是找到传入节点后继节点,将其唤醒(排除掉状态cancel即waitStatus > 0节点)。 公平锁和非公平锁 ReentrantLock构造方法接受一个可选公平参数

    46220

    面试官:从源码角度讲讲ReentrantLock及队列同步器(AQS)

    ,而是简单地判断自己前驱是否头节点,这样就使得节点释放符合 FIFO,并且对于方便对过早通知进行处理。...不过在此之前需要进行两个条件判断h != null是为了防止队列为,即没有任何线程处于等待队列,那么也就不需要进行唤醒操作; h.waitStatus !...:通过判断当前线程是否已经获取了锁线程来决定获取操作是否成功,如果是则将同步状态值增加并返回 true,表示获取同步状态成功。...由于头结点是当前获取锁线程,队列第二个结点代表线程优先级最高。那么只要判断队列第二个结点是否存在以及这个结点是否代表当前线程就行了。...为什么非公平锁性能好 非公平锁对锁竞争是抢占式(对于已经处于等待队列中线程除外),线程在进入等待队列之前可以进行两次尝试,这大大增加了获取锁机会。

    32220

    ReentrantLock 锁详解

    ,当资源空闲时,它总是会先判断 sync队列(AbstractQueuedSynchronizer数据结构)是否有等待时间更长线程,如果存在,则将该线程加入到等待队列尾部,实现了公平获取原则。...如果再有线程要获取锁,依次在队列往后排队即可。 回到上边代码,hasQueuedPredecessors是公平锁加锁时判断等待队列是否存在有效节点方法。...= t && ((s = h.next) == null || s.thread != Thread.currentThread());为什么判断头结点下一个节点?...(可能是非公平锁被抢占了)或者是p不为头结点,这个时候就要判断当前node是否要被阻塞(被阻塞条件:前驱节点waitStatus-1),防止无限循环浪费资源。...,1:判断当前节点前驱节点是否SIGNAL,2:如果不是,则把前驱节点设置SINGAL看是否成功 24 // 如果1和2有一个true,再判断当前节点线程是否null 25

    52060

    ReentrantLock 源码浅析

    = t』判断true,认为当下是一个非等待队列,那么接着执行『s = h.next』就会抛出NPE异常了。...我们接下看下面的步骤,来说明为什么这么做就可以了。 ② 在获取完t、h之后,我们接着先判断h != t』,该判断用意在于,判断当前队列是否。如果true则说明,当前队列非。...如果false 则说明当前队列为的话,方法就直接结束了,并返回false。 但是请注意,当『h !...next值进行赋值,所以我们需要“s = h.next”是否null进行判断,如果’null’,则说明当前等待队列正在被初始化,并且有一个线程正在入队操作。...并且该方法会在获取锁情况下才会返回: a)若在等待获取锁过程,当前线程被标识为了中断,则在方法返回时候返回true;接着判断interruptMode是否等于“THROW_IE”,如果true

    1.8K94

    从ReentrantLock实现看AQS原理及应用

    如果再有线程要获取锁,依次在队列往后排队即可。 回到上边代码,hasQueuedPredecessors是公平锁加锁时判断等待队列是否存在有效节点方法。...= t && ((s = h.next) == null || s.thread != Thread.currentThread());为什么判断头结点下一个节点?第一个节点储存数据是什么?...(可能是非公平锁被抢占了)或者是p不为头结点,这个时候就要判断当前node是否要被阻塞(被阻塞条件:前驱节点waitStatus-1),防止无限循环浪费资源。...,1:判断当前节点前驱节点是否SIGNAL,2:如果不是,则把前驱节点设置SINGAL看是否成功 // 如果1和2有一个true,再判断当前节点线程是否null // 如果上述条件都满足...= 0) unparkSuccessor(h); return true; } return false; } 这里判断条件为什么h !

    1.7K11

    Java并发-AbstractQueuedSynchronizer(AQS)JDK源代码分析

    enq方法会在addWaiter()方法得到调用,是属于AbstractQueuedSynchronizer方法,即:java.util.concurrent.locks.AbstractQueuedSynchronizer...如果 tail 结点,则将 head 结点指向一个结点 2.2.3 acquireQueued(Node, int),即java.util.concurrent.locks.AbstractQueuedSynchronizer...如果是,则表明当前结点是队列第一个有效结点,有最优先执行权力,只等得到锁资源了,即判断下面语句是否真: 根据tryAcquire() 返回布尔值判断当前线程是否获取到了锁(具体方法有子类实现提供...,判断当前结点前继结点状态是否 SIGNAL,如果不是则尝试设置前继结点状态 SIGNAL。...又有一些不同之处: 共享模式下方法调用呈现更加集成化,比如addWaiter()方法直接放置于doAcquireShared方法内部,而独占模式是作为参数放置于方法体参数; 共享模式多了一个资源数判断

    81420

    基于AQSReentrantLock实现原理

    = Thread.currentThread()); } hasQueuedPredecessors是公平锁加锁时判断等待队列是否存在有效节点方法。...= t && ((s = h.next) == null || s.thread != Thread.currentThread());为什么判断头结点下一个节点?第一个节点储存数据是什么?...(可能是非公平锁被抢占了)或者是p不为头结点,这个时候就要判断当前node是否要被阻塞(被阻塞条件:前驱节点waitStatus-1),防止无限循环浪费资源。...为了防止因死循环导致CPU资源被浪费,我们会判断前置节点状态来决定是否要将当前线程挂起 4、取消自旋等待 同样,在acquireQueued方法Finally代码cancelAcquire:...SIGNAL,2:如果不是,则把前驱节点设置SINGAL看是否成功 // 如果1和2有一个true,再判断当前节点线程是否null // 如果上述条件都满足,把当前节点前驱节点后继指针指向当前节点后继节点

    42510

    从源码角度彻底理解ReentrantLock(重入锁)

    第一个if分句中,当前线程首先会判断前驱结点是否是头结点,如果是则尝试获取锁,获取锁成功则会设置当前结点头结点(更新头指针)。为什么必须前驱结点头结点才尝试去获取锁?...=null是为了防止队列为,即没有任何线程处于等待队列,那么也就不需要进行唤醒操作 h.waitStatus !...= Thread.currentThread()); } 从方法名我们就可知道这是判断队列是否有优先级更高等待线程,队列哪个线程优先级最高?...由于头结点是当前获取锁线程,队列第二个结点代表线程优先级最高。 那么我们只要判断队列第二个结点是否存在以及这个结点是否代表当前线程就行了。...6.2 为什么非公平锁性能好 非公平锁对锁竞争是抢占式(队列中线程除外),线程在进入等待队列前可以进行两次尝试,这大大增加了获取锁机会。

    55340

    多线程应用 - 超详细AQS详情

    ,具体实现会在其他类,可以看下该方法引用。...公平锁首先会判断state数值如果0,表示锁没有被任何线程所占用,可以让线程获取锁资源,通过cas修改state,并设置锁资源拥有者当前线程。...如果锁state数值不为0,需要判断获取锁资源是否当前线程,如果不是直接返回失败,如果是,表示遇到了可重入情况,将锁计数器+1。...而在AQS,会先判断ReentrantLocktryAcquire方法是否成功,如果不成功,假设第一个线程加锁成功,第二个线程调用获取锁资源方法,则第二个线程会加入到等待队列。...判断逻辑,需要获取锁结点是头结点,那么将该头结点对应线程获取锁资源,并将原来头结点回收掉,自旋结束。如果不是头结点,则需要判断是否需要挂起线程。

    50220
    领券