幼儿饰品瑜伽美体用品微软
投稿投诉
微软创意
爱情通信
用品婚姻
爱好看病
美体软件
影音星座
瑜伽周边
星座办公
饰品塑形
搞笑减肥
幼儿两性
智家潮品

JAVA并发之ReentrantLock原理解析

  Java从版本5开始,在java。util。concurrent。locks包内给我们提供了除了synchronized关键字以外的几个新的锁功能的实现,ReentrantLock就是其中的一个。但是这并不意味着我们可以抛弃synchronized关键字了。
  在这些锁实现之前,如果我们想实现锁的功能,只能通过synchronized关键字,例子如下:privatestaticvolatileintvalue;publicstaticvoidmain(){RunnablerunnewRunnable(){Overridepublicvoidrun(){for(inti0;i1000;i){increaseBySync();}}};Threadt1newThread(run);Threadt2newThread(run);t1。start();t2。start();while(Thread。activeCount()1){Thread。yield();}System。out。println(value);}privatestaticsynchronizedintincreaseBySync(){returnvalue;}
  有了ReentrantLock之后,我们可以这样写:privatestaticvolatileintvalue;privatestaticLocklocknewReentrantLock();publicstaticvoidmain(String〔〕args){testIncreaseWithLock();}publicstaticvoidmain(){RunnablerunnewRunnable(){Overridepublicvoidrun(){try{lock。lock();for(inti0;i1000;i){value;}}finally{lock。unlock();}}};Threadt1newThread(run);Threadt2newThread(run);t1。start();t2。start();while(Thread。activeCount()1){Thread。yield();}System。out。println(value);}
  以上两段代码都可以实现value值同步自增1,并且value都能得到正确的值2000。下面我们就来分析下ReentrantLock有哪些功能以及它底层的原理。可重入锁
  从名字我们就可以看出ReentrantLock是可重入锁。可重入锁是指当某个线程已经获得了该锁时,再次调用lock()方法可以再次立即获得该锁。
  举个例子,当某个线程在执行methodA()时,假设已经获得了锁,这是当它执行到methodB()时可以立即获得methodB里面的锁,因为两个方法是调用的同一把锁。privatestaticLocklocknewReentrantLock();publicstaticvoidmethodA(){try{lock。lock();dosomethingmethodB();}finally{lock。unlock();}}publicstaticvoidmethodB(){try{lock。lock();dosomthing}finally{lock。unlock();}}
  synchronized也是可重入锁,有兴趣的同学可以自己写个例子测试下。公平锁
  通过源码我们可以看到ReentrantLock支持公平锁,并且默认是非公平锁。ReentrantLock源码publicReentrantLock(){syncnewNonfairSync();}ReentrantLock源码publicReentrantLock(booleanfair){syncfair?newFairSync():newNonfairSync();}
  下面是非公平锁和公平锁的lock()方法实现,从两个lock()方法我们可以看到,它们的不同点是在调用非公平锁的lock()方法时,当前线程会尝试去获取锁,如果获取失败了则调用acquire(1)方法入队列等待;而调用公平锁的lock()方法当前线程会直接入队列等待(acquire方法涉及到AQS下面会讲到)。ReentrantLock源码,非公平锁finalvoidlock(){if(compareAndSetState(0,1))setExclusiveOwnerThread(Thread。currentThread());elseacquire(1);}ReentrantLock源码,公平锁finalvoidlock(){acquire(1);}
  而synchronized是一个非公平锁。超时机制
  ReentrantLock还提供了超时机制,当调用tryLock()方法,当前线程如果获取锁失败会立刻返回;而当调用带参tryLock()方法时,当前线程如果在设置的timeout时间内未获得锁,也会立刻返回。而这些功能背后主要是依赖AQS实现的。ReentrantLock源码publicbooleantryLock(){returnsync。nonfairTryAcquire(1);}ReentrantLock源码publicbooleantryLock(longtimeout,TimeUnitunit)throwsInterruptedException{returnsync。tryAcquireNanos(1,unit。toNanos(timeout));}
  synchronized没有这个功能。可被中断
  ReentrantLock有一个lockInterruptibly()方法,它会最终调用AQS的两个方法:
  AQS方法一中如果当前线程被中断则抛出InterruptedException,否则尝试去获取锁,获取成功则返回,获取失败则调用aqs方法二doAcquireInterruptibly()。
  AQS方法二中在for循环线程自旋中也会判断当前线程是否被标记为中断,如果是也会抛出InterruptedException。
  doAcquireInterruptibly()的细节我们在下面讲解AQS的时候会重点介绍,它和doAcquire()方法很类似,唯一区别是会抛出InterruptedException。lock方法publicvoidlockInterruptibly()throwsInterruptedException{sync。acquireInterruptibly(1);}aqs方法一publicfinalvoidacquireInterruptibly(intarg)throwsInterruptedException{if(Thread。interrupted())thrownewInterruptedException();if(!tryAcquire(arg))doAcquireInterruptibly(arg);}aqs方法二privatevoiddoAcquireInterruptibly(intarg)throwsInterruptedException{finalNodenodeaddWaiter(Node。EXCLUSIVE);booleanfailedtrue;try{for(;;){finalNodepnode。predecessor();if(pheadtryAcquire(arg)){setHead(node);p。nextnull;helpGCfailedfalse;return;}if(shouldParkAfterFailedAcquire(p,node)parkAndCheckInterrupt())thrownewInterruptedException();}}finally{if(failed)cancelAcquire(node);}}AQS(AbstractQueueSynchronizer)
  AQS是一个基于队列的同步器,它是一个抽象类,主要提供了多线程获取锁时候的排队等待和激活机制,ReentrantLock内部有两个基于AQS实现的子类,分别针对公平锁和非公平锁做了支持。
  下面我们以公平锁为例,讲解下ReentrantLock是如何依赖AQS实现其功能的。获得锁涉及到的主要源代码和解释如下:AQS源码,公平锁的lock()方法会直接调用该方法这里当前如果获取失败会调用acquireQueued方法addWaiter方法主要是将当前线程加入AQS内部队列的尾部publicfinalvoidacquire(intarg){if(!tryAcquire(arg)acquireQueued(addWaiter(Node。EXCLUSIVE),arg))selfInterrupt();}ReentrantLock中实现公平锁的AQS子类的方法protectedfinalbooleantryAcquire(intacquires){finalThreadcurrentThread。currentThread();intcgetState();c0表示当前AQS为初始状态,可以尝试获取锁,如获取成功则返回trueif(c0){if(!hasQueuedPredecessors()compareAndSetState(0,acquires)){setExclusiveOwnerThread(current);returntrue;}}只有当前线程是已经获取了该锁的线程才能再次获取锁(可重入锁)并返回trueelseif(currentgetExclusiveOwnerThread()){intnextccacquires;if(nextc0)thrownewError(Maximumlockcountexceeded);setState(nextc);returntrue;}返回false获取失败returnfalse;}AQS源码finalbooleanacquireQueued(finalNodenode,intarg){booleanfailedtrue;try{booleaninterruptedfalse;for(;;){finalNodepnode。predecessor();这里如果当前线程对应的队列里的Node的前置Node是head,则尝试获取锁,并成功返回if(pheadtryAcquire(arg)){setHead(node);p。nextnull;helpGCfailedfalse;returninterrupted;}shouldParkAfterFailedAcquire方法标记当前线程Node的前置Node的waitStatus为SIGNAL,意思是当你从队列移除时记得要唤醒我哦parkAndCheckInterrupt方法会让当前线程挂起,停止自旋,免得白白浪费CPU资源if(shouldParkAfterFailedAcquire(p,node)parkAndCheckInterrupt())interruptedtrue;}}finally{if(failed)cancelAcquire(node);}}
  假设现在有线程A、B、C同时去获取同一把锁,大概的流程是这样的,这里假设线程A获得锁并成功返回,线程B和C则依次调用上面的方法,进入AQS的等待队列并最终被挂起。
  这时线程A做完自己该做的事情了,它在finally块中调用了unlock方法,这时我们再看下相关的源代码。AQS源码,当前线程在释放锁的同时,会判断它所在Node的waitStatus有没有被它的后继结点标记,如果被标记了,那就唤醒后继结点对应的线程publicfinalbooleanrelease(intarg){if(tryRelease(arg)){Nodehhead;if(h!nullh。waitStatus!0)unparkSuccessor(h);returntrue;}returnfalse;}AQS源码,主要关注最下面LockSupport。unpark(s。thread),唤醒后继结点线程privatevoidunparkSuccessor(Nodenode){Ifstatusisnegative(i。e。,possiblyneedingsignal)trytoclearinanticipationofsignalling。ItisOKifthisfailsorifstatusischangedbywaitingthread。intwsnode。waitStatus;if(ws0)compareAndSetWaitStatus(node,ws,0);Threadtounparkisheldinsuccessor,whichisnormallyjustthenextnode。Butifcancelledorapparentlynull,traversebackwardsfromtailtofindtheactualnoncancelledsuccessor。Nodesnode。next;if(snulls。waitStatus0){snull;for(Nodettail;t!nullt!node;tt。prev)if(t。waitStatus0)st;}if(s!null)LockSupport。unpark(s。thread);}
  线程A释放锁时,会唤醒head结点的后继结点也就是线程B,此时线程B就可以继续for循环里面自旋并成功获得锁了。unsafe相关
  之前介绍AtomicInteger的时候提到Unsafe对象,AtomicInteger用到了Unsafe对象的CAS功能(底层是cpu提供的功能)。
  ReentrantLock除了用到了CAS之外,还用到了Unsafe的pack和unpack两个方法(LockSupport当中),除了性能更好之外,它可以精确的唤醒某一个线程。Demo代码位置
  srcmainjavanetweichitechjucReentrantLockTest。java小西学编程javalearningGitee。com相关文章
  JAVA并发之AtomicInteger原理分析

意奥委会主席谈新球场我不担心圣西罗,这里将举行2026年冬奥直播吧3月3日讯近期关于米兰和国米准备建设新球场的报道很多,而意大利奥委会主席乔瓦尼马拉戈表示,自己并不担心圣西罗球场的未来。马拉戈主席称:是否担心圣西罗?我看了相关新闻……华为Mate50pro真实上手使用体验感受,详细聊聊这款手机如果您喜欢我的文章,欢迎您点击左上角的关注后续将第一时间为您带来最新手机资讯!华为Mate50pro这款手机发布已经有段时间了,我也有点按耐不住内心的的躁动,于是借用好友……张文宏预判第二波感染高峰时间确定,做好这6件事,提前准备张文宏预判:第二波感染高峰时间确定,做好这6件事,提前准备。随着第一波疫情的落幕,我们也迎来了疫情后的第一个春天,由于多种奥密克戎变异株的出现,我们也要做好面对第二波疫情……红颜昨夜尚有梦,远方君子可有解(六)醉后方知酒浓,醒后方知梦空,原来残花落尽,竟痛的如此斑驳。是谁在你的佛龛前,挥洒了一生的诺言,口吐金经,句句真言,你的佛语里可曾遗留曾经的生死之恋。一个转身的薄凉,谁在谁体验,……渤海银行被依法罚款860万元因未准确反映信用风险信息等据银保监网站近日公布的《中国银行保险监督管理委员会行政处罚信息公开表(银保监罚决字〔2023〕21号)》显示,渤海银行股份有限公司被依法罚款860万元,其涉及的主要违法违规事实……原创枫叶岁月深处人逐年华老,寒随雨意增。走过风风雨雨,跌跌撞撞,沟沟坎坎的旅途,对世事早已了然于胸,对人生亦开始大彻大悟。人生,是一条没有回程的单行线,我们所能做的,是不悲不喜,不忧不惧……爆料称GTA6已完成开发,已进入打磨阶段要说家喻户晓的PC游戏,GTA系列绝对能排的上号,甚至很多人接触PC的第一款游戏,便是此类游戏。当初GTA5刚发布时,教长就见到不少玩家掏出珍藏已久的古董电脑,就算卡成P……简单易做的冰糖草莓,草莓和蓝莓,酸酸甜甜,不比北京糖葫芦差冰糖与草莓的巧妙结合,中和草莓微酸的味道,又避免吃冰糖过分甜腻的口感,还能起到清热去火,养肝明目的作用,真是春季不可多得的一道养生佳品。简单步骤1。准备:草莓、蓝莓……火山引擎DataTester在字节,AB实验是一种信仰更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,并进入官方交流群进入数字经济时代,要用数据驱动业务增长已经成为各个行业的共识,但很多企业还没能真正掌握这项能力……怼马云,贬马化腾,看不起腾讯和支付宝,兰世立到底是何人?2月财经新势力一个多次入狱的罪犯,竟然在公开场合当众贬低马云、马化腾、王健林等一众大佬都是模仿者,毫无创新能力,更是直言支付宝、微信支付全是外国产业的赝品。他究竟是谁?其……开学第二周,女儿身上的磨蹭被我治好了,这几个经验分享给大家家长百问百答文兰妈谈育儿孩子拖延的最主要原因之一,就是他们太过迷茫、缺乏努力的方向感,如果对未来的愿景模糊不清又怎会有前进的动力呢?情况描述:磨蹭女儿终于开学……元宵节剩下汤圆怎么消耗试试这个脆皮汤圆烤年糕神仙吃法软糯爆浆元宵节剩下的汤圆怎么消耗?我们之前有用汤圆做过蛋黄酥,也做过拉丝的面包,汤圆还可以油炸,还可以裹着椰蓉当糯米糍吃,今天分享一个汤圆新的神仙吃法,很火的烤年考和汤圆结合在一起,会……
照得龇牙咧嘴,修成国色天香,11位女星的前后对比好夸张肤若凝脂,眼如水杏,面似桃花。在人们的印象里,女明星好像都是这样的,但这可能是个大骗局。跨年会成照妖镜每年的最后一天夜晚是女明星变超人的时候。这一夜,内娱女明……目中无人陈坤,当众怒砸谢霆锋,大骂学生,王菲4字犀利回怼2013年9月27日,白举纲参加《快乐男声》在舞台上尽显歌喉,评委席上的陈坤突然把耳机砸向谢霆锋。可把中间的陶晶莹吓了一跳,台上的白举纲更是目瞪口呆,当年到底发生了什么?他们二……看到福建队黎伊扬的表现,我就可惜另外两个选秀球员看到福建队黎伊扬目前的表现,我真的感觉挺开心的,今年选秀结束,我就发文预计了前十顺位谁最可能打出来,其中排名第一的就是黎伊扬。当时有些粉丝比较认可我的那个观点,我们认为黎伊扬最……76岁老人顿顿吃肉,血管依旧通畅,与运动无关,秘诀是3件事随着社会不断发展,人们生活水平有所提高,越来越多的人不注重饮食和生活习惯,给予一些疾病可乘之机,特别是心脑血管疾病,跟饮食有着密不可分的关系,甚至有些中老年人为了养生只吃素而不……东道主杀手!韩国短道扔手链坑刘少林,挑衅武大靖引中韩冲突短道速滑世界杯已经结束了3站比赛,韩国队依然是绝对焦点,虽然成绩不算出色,但绝对抢戏。在北京,韩国短道速滑队与东道主中国队王牌武大靖发生冲突,在匈牙利,韩国短道速滑队又坑了东道……看完这个表是不是发现该换手机了,先别急看完再决定手机,现在大家都在追求玩最高大上的,都想体验最新的芯片,最新的功能,为了尝鲜多花几千块钱,对很多手机发烧友来说算不了什么。很多手机生产商也把握透了消费者这种心态,所以,他……世界足球历史最高11人阵容,锋线三叉戟全部2米以上,战力几何整个阵容不仅平均身高超过195厘米,而且各个位置没有短板,都是世界豪强球队的绝对主力球员,中场高大但技术细腻,锋线三叉戟更是全部都在2米以上,头球轰炸将是所有球队的噩梦。门将:……古时候的人都是这样养生的!我们可以借鉴一下!现在很多年轻人熬夜,加班,抽烟,喝酒,没有一点点节制,这对于身体来讲是很不友好的。熬夜伤神,抽烟伤肺,喝酒伤肝,这些行为对于我们的身体有莫大的伤害。在黄帝内经养生篇讲到养……中药大数据盘点2023年需求反弹,香料类品种行情会涨吗?作者:凌云来源:天地云图中药产业大数据香料类品种一直以来都是药材市场上颇受商家关注的热点品种之一,但20202022年因疫情影响需求萎缩,香料类品种行情低迷还是出乎……NASA提出了一种可直接观察到暗物质影响的方法银河系的图片显示,数十亿颗恒星以螺旋状排列并从中心向外辐射,其中间有发光的气体。但我们的眼睛只能瞥见支撑我们银河系的表面。我们银河系约95的质量是看不见的,它们不会跟光发生作用……CBA三消息亚当斯新年送祝福,巴斯不会回归辽篮,常林或将离队CBA联赛目前正处于新年放假中,除了国内球员送祝福以外,一些曾经效力于中国联赛的外援也纷纷送出了自己的祝福,其中有前辽宁队外援梅奥和巴斯,上海队外援弗雷戴特以及新疆队外援亚当斯……3消息!篮网CEO离队!美媒建议快船3换2交易蒙克,詹皇或离大家好!我们今天来聊聊NBA,为大家分享几则NBA消息:篮网巨头离队!曝快船3换2交易蒙克方案,詹皇或离开湖人。首先,篮网巨头离队!据篮网队随队记者报道,篮网巨头,也就是……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网