当前位置: 首页 > 后端技术 > Java

JavaJUCReentrantLock分析

时间:2023-04-01 14:02:12 Java

鐙崰閿丷eentrantLock鍘熺悊浠嬬粛ReentrantLock鏄竴绉嶅彲閲嶅叆鐨勭嫭鍗犻攣锛屽悓涓€鏃跺埢鍙兘鏈変竴涓嚎绋嬭幏鍙栭攣锛屽叾浠栬幏鍙栭攣鐨勭嚎绋嬩細琚樆濉炵劧鍚庢斁鍏ヨ绾跨▼鐨凙QS鍧椾腑閿佸畾闃熷垪銆傚畠涓巗ynchronized鍏锋湁鐩稿悓鐨勫熀鏈涓哄拰璇箟锛屼絾ReentrantLock鏇村姞鐏垫椿鍜屽己澶э紝澧炲姞浜嗚疆璇€佽秴鏃躲€佷腑鏂瓑楂樼骇鍔熻兘锛岃繕鏀寔鍏钩閿佸拰闈炲叕骞抽攣銆備粠绫诲浘涓彲浠ョ湅鍑猴紝ReentrantLock渚濈劧鏄娇鐢ˋQS瀹炵幇鐨勶紝鍐呴儴鍙互鏍规嵁鍙傛暟閫夋嫨鏄叕骞抽攣杩樻槸闈炲叕骞抽攣銆傞粯璁ゆ槸闈炲叕骞抽攣銆俻ublicReentrantLock(){sync=newNonfairSync();}publicReentrantLock(booleanfair){sync=fair锛焠ewFairSync():newNonfairSync();}Sync绫荤洿鎺ョ户鎵夸簡AQS绫伙紝鍏跺瓙绫籒onfairSync鍜孎airSync鍒嗗埆瀹炵幇浜嗛潪鍏钩鍜屽叕骞宠幏鍙栭攣鐨勭瓥鐣ャ€俿taticfinalclassNonfairSyncextendsSync{}staticfinalclassFairSyncextendsSync{}ReentrantLock涓瑼QS鐨勭姸鎬佸€艰〃绀虹嚎绋嬭幏鍙栭攣鐨勯噸鍏ユ鏁般€傞粯璁ゆ儏鍐典笅锛岀姸鎬佸€间负0锛岃繖鎰忓懗鐫€褰撳墠娌℃湁绾跨▼鎸佹湁銆傚綋涓€涓嚎绋嬬涓€娆¤幏鍙栭攣鏃讹紝浼氬皾璇曚娇鐢–AS灏嗙姸鎬佽缃负1锛屽鏋淐AS鎴愬姛锛屽垯褰撳墠绾跨▼鑾峰彇閿侊紝鐒跺悗灏嗛攣鎸佹湁鑰呰褰曚负褰撳墠绾跨▼銆傜嚎绋嬬浜屾鑾峰彇閿佸悗锛岀姸鎬佽缃负2锛屼篃灏辨槸閲嶅叆璁℃暟銆傚綋绾跨▼閲婃斁閿佹椂锛屼細灏濊瘯浣跨敤CAS灏唖tate鍑?锛屽鏋滃噺1鍚庝负0锛屽垯閲婃斁閿併€傝幏鍙栭攣voidlock()publicvoidlock(){sync.lock();}绾跨▼璋冪敤璇ユ柟娉曟椂锛屽鏋滃綋鍓嶉攣娌℃湁琚叾浠栫嚎绋嬪崰鐢紝涓斿綋鍓嶇嚎绋嬩箣鍓嶆病鏈夎幏鍙栬繃閿侊紝鍒欏綋鍓嶇嚎绋嬭幏鍙栧埌瀹冿紝鐒跺悗灏嗛攣鐨勬墍鏈夎€呰缃负鑷繁锛岀劧鍚庡皢AQS鐨勭姸鎬佽缃负1锛岀劧鍚庤繑鍥炪€傚鏋滃綋鍓嶇嚎绋嬪凡缁忚幏寰椾簡閿侊紝瀹冨彧鏄皢AQS鐨勭姸鎬佸姞1骞惰繑鍥炪€傚鏋滈攣宸茬粡琚叾浠栫嚎绋嬫寔鏈夛紝鍒欏綋鍓嶇嚎绋嬩細杩涘叆AQS鐨勯樆濉為槦鍒楋紝琚樆濉炴寕璧枫€俁eentrantLock涓殑lock()鏂规硶濮旀墭缁欎簡sync绫伙紝sync鏍规嵁ReentrantLock鐨勬瀯閫犲嚱鏁伴€夋嫨浣跨敤NonfairSync杩樻槸FairSync銆傛垜浠厛鏉ョ湅涓€涓嬮潪鍏钩閿佺殑瀹炵幇銆俧inalvoidlock(){//CAS璁剧疆鐘舵€佸€糹f(compareAndSetState(0,1))setExclusiveOwnerThread(Thread.currentThread());else//璋冪敤AQS鐨刟cquire鏂规硶acquire(1);}鍦╨ock()涓厛璋冪敤compareAndSetState鏂规硶锛屽洜涓洪粯璁tate鍊间负0锛屾墍浠ョ涓€涓嚎绋嬪湪璋冪敤杩欎釜鏂规硶鏃朵細閫氳繃CAS璁剧疆涓?绗竴娆★紝鐒跺悗鎴愬姛鑾峰彇鍒伴攣锛岀劧鍚庨€氳繃绾跨▼鐨剆etExclusiveOwnerThread鏂规硶灏嗛攣鎸佹湁鑰呰缃负褰撳墠鐨勩€傚綋鍏朵粬绾跨▼閫氳繃lock()鑾峰彇閿佹椂锛孋AS浼氬け璐ワ紝杩涘叆else璋冪敤acquire(1)鏂规硶锛屼紶鍙備负1銆傛垜浠啀鏉ョ湅鐪媋cquire鏂规硶銆俻ublicfinalvoidacquire(intarg){if(!tryAcquire(arg)&&acquireQueued(addWaiter(Node.EXCLUSIVE),arg))selfInterrupt();}涓婁竴绡囨枃绔犳彁鍒癆QS娌℃湁鎻愪緵tryAcquire鏂规硶鐨勫疄鐜帮紝鎴戜滑鏉ョ湅鐪婻eentrantLock閲嶅啓鐨則ryAcquire鏂规硶锛岃繖閲屾垜浠繕鏄湅鐪嬮潪鍏钩閿佺殑瀹炵幇銆俿taticfinalclassNonfairSyncextendsSync{finalvoidlock(){if(compareAndSetState(0,1))setExclusiveOwnerThread(Thread.currentThread());鍚﹀垯鑾峰彇锛?锛夛紱}//璋冪敤杩欎釜鏂规硶protectedfinalbooleantryAcquire(intacquires){returnnonfairTryAcquire(acquires);}}finalbooleannonfairTryAcquire(intacquires){finalThreadcurrent=Thread.currentThread();intc=getState();if(c==0){if(compareAndSetState(0,acquires)){setExclusiveOwnerThread(current);杩斿洖鐪燂紱}}elseif(current==getExclusiveOwnerThread()){intnextc=c+acquires;if(nextc<0)//婧㈠嚭thrownewError("Maximumlockcountexceeded");璁剧疆鐘舵€侊紙涓嬩竴姝ワ級锛涜繑鍥炵湡锛泒returnfalse;}璇ユ柟娉曢鍏堟鏌ュ綋鍓峴tate鍊兼槸鍚︿负0锛屽鏋滀负0鍒欒鏄庨攣褰撳墠绌洪棽锛岀劧鍚庡皾璇旵AS鑾峰彇閿併€傛垚鍔熷悗鐘舵€佺疆1锛岀劧鍚庨攣鎸佹湁鑰呬负褰撳墠绾跨▼銆傚鏋渟tate涓嶄负0锛屽垯琛ㄧず璇ラ攣宸茶鎸佹湁銆傚鏋滄寔鏈夎€呮伆濂芥槸褰撳墠绾跨▼锛屽垯灏嗙姸鎬佸姞1骞惰繑鍥瀟rue銆傞渶瑕佹敞鎰忕殑鏄紝濡傛灉nextc<0锛岄攣鍙兘浼氭孩鍑恒€傚鏋滃綋鍓嶇嚎绋嬩笉鏄寔鏈夎€咃紝鍒欒繑鍥瀎alse锛岀劧鍚庡姞鍏QS闃诲闃熷垪銆傛垜浠潵鐪嬬湅鍏钩閿佺殑瀹炵幇銆俻rotectedfinalbooleantryAcquire(intacquires){finalThreadcurrent=Thread.currentThread();intc=getState();if(c==0){//鍏钩绛栫暐if(!hasQueuedPredecessors()&&compareAndSetState(0,acquires)){setExclusiveOwnerThread(current);杩斿洖鐪燂紱}}elseif(current==getExclusiveOwnerThread()){intnextc=c+acquires;if(nextc<0)thrownewError("瓒呰繃鏈€澶ч攣璁℃暟");璁剧疆鐘舵€侊紙涓嬩竴姝ワ級锛涜繑鍥炵湡锛泒returnfalse;}鍏钩閿佺殑tryAcquire鏂规硶鍜岄潪鍏钩閿佺殑鍖哄埆鍦ㄤ簬澶氫簡涓€涓猦asQueuedPredecessors()鏂规硶锛岃繖鏄疄鐜板叕骞抽攣鐨勬牳蹇冧唬鐮併€俻ublicfinalbooleanhasQueuedPredecessors(){//璇诲彇澶磋妭鐐筃odet=tail;//璇诲彇灏捐妭鐐筃odeh=head;//s鏄涓€涓妭鐐筯鐨勫悗缁ц妭鐐筃odes锛況eturnh!=t&&((s=h.next)==null||s.thread!=Thread.currentThread());}璇ユ柟娉曚腑锛岀敱浜庨槦鍒楁槸FIFO锛屾墍浠ラ渶瑕佸垽鏂槸鍚︽湁闃熷垪涓凡鎺掗槦鐨勭浉鍏崇嚎绋嬬殑鑺傜偣銆傚鏋滄槸锛屽垯杩斿洖true锛岃〃绀鸿绾跨▼闇€瑕佹帓闃燂紱濡傛灉涓嶆槸锛屽垯杩斿洖false锛岃〃绀鸿绾跨▼涓嶉渶瑕佹帓闃熴€傞鍏堟垜浠湅绗竴涓潯浠秇!=t锛屽ご鑺傜偣鍜屽熬鑺傜偣閮芥槸null锛屼篃灏辨槸璇撮槦鍒楄繕鏄┖鐨勶紝杩炲垵濮嬪寲閮芥病鏈夊畬鎴愶紝鑷劧浼氳繑鍥瀎asle鏃犻渶鎺掗槦銆傚ご鑺傜偣鍜屽熬鑺傜偣涓嶄负绌鸿€屾槸鐩哥瓑鐨勶紝璇存槑澶磋妭鐐瑰拰灏捐妭鐐归兘鎸囧悜涓€涓厓绱狅紝璇存槑闃熷垪涓彧鏈変竴涓妭鐐癸紝姝ゆ椂涓嶉渶瑕佹帓闃燂紝鍥犱负闃熷垪涓殑绗竴涓妭鐐逛笉鍙備笌闃熷垪锛屽畠淇濇寔鍚屾鐘舵€侊紝閭d箞绗簩涓紶鍏ヨ妭鐐逛笉闇€瑕佹帓闃燂紝鍥犱负瀹冪殑鍓嶉┍鑺傜偣鏄ご鑺傜偣锛屾墍浠ョ浜屼釜浼犲叆鑺傜偣灏辨槸绗竴涓妭鐐瑰彲浠ユ甯歌幏鍙栧悓姝ョ姸鎬侊紝绗笁涓妭鐐归渶瑕佹帓闃熺瓑寰呯浜屼釜鑺傜偣閲婃斁鍚屾鐘舵€併€傛帴涓嬫潵鎴戜滑鐪嬬浜屼釜鏉′欢锛?s=h.next)==null锛屽鏋渉!=t&&s==null锛岃鏄庢湁涓€涓厓绱犱細浣滀负AQS鐨勭涓€涓妭鐐瑰叆闃燂紝閭d箞杩斿洖鐪熴€傛帴涓嬫潵鐪嬬涓変釜鏉′欢s.thread!=Thread.currentThread()锛屽垽鏂悗缁ц妭鐐规槸鍚︿负褰撳墠绾跨▼銆傪煓嬸煆烩€嶏笍姣斿case1锛歨!=t杩斿洖true锛?s=h.next)==null杩斿洖false锛宻.thread!=Thread.currentThread()杩斿洖falsefirsth!=t杩斿洖true锛岃鏄庨槦鍒椾腑鑷冲皯鏈変袱涓笉鍚岀殑鑺傜偣锛?s=h.next)==null杩斿洖false锛岃鏄庡ご鑺傜偣鍚庢湁鍚庣户鑺傜偣锛泂.thread!=Thread.currentThread()杩斿洖false锛岃鏄庡綋鍓嶇嚎绋嬪拰鍚庣户鑺傜偣鐩稿悓锛涜〃绀鸿疆鍒板綋鍓嶈妭鐐瑰皾璇曡幏鍙栧悓姝ョ姸鎬侊紝涓嶉渶瑕佹帓闃燂紝杩斿洖false銆傪煓嬸煆烩€嶏笍姣斿case2锛歨!=t杩斿洖true锛?s=h.next)==null杩斿洖true棣栧厛h!=t杩斿洖true锛岃鏄庨槦鍒椾腑鑷冲皯鏈変袱涓笉鍚岀殑鑺傜偣锛?s=h.next)==null杩斿洖true锛岃〃绀哄ご鑺傜偣涔嬪悗娌℃湁鍚庣户鑺傜偣锛屽嵆鍝ㄥ叺鑺傜偣锛涜繑鍥瀟rue锛岃〃绀洪渶瑕佹帓闃熴€傪煓嬸煆烩€嶏笍姣斿鎯呭喌涓夛細h!=t杩斿洖true锛?s=h.next)==null杩斿洖false锛宻.thread!=Thread.currentThread()棣栧厛杩斿洖trueh!=t杩斿洖true锛岃鏄庨槦鍒椾腑鑷冲皯鏈変袱涓笉鍚岀殑鑺傜偣锛?s=h.next)==null杩斿洖false锛岃鏄庡ご鑺傜偣鍚庢湁鍚庣户鑺傜偣锛泂.thread!=Thread.currentThread()杩斿洖true锛岃鏄庡悗缁ц妭鐐圭殑绾跨▼涓嶆槸褰撳墠绾跨▼锛屼篃灏辨槸璇村墠闈㈠凡缁忔湁浜哄湪鎺掗槦浜嗭紝浣犺繕鏄€佽€佸疄瀹炲幓鎺掗槦鍚с€傝繑鍥炵湡锛岃〃绀洪渶瑕侀槦鍒椼€倂oidlockInterruptibly()publicvoidlockInterruptibly()throwsInterruptedException{sync.acquireInterruptibly(1);}publicfinalvoidacquireInterruptibly(intarg)throwsInterruptedException{//濡傛灉褰撳墠绾跨▼琚腑鏂紝鍒欐姏鍑哄紓甯竔f(Thread.interrupted())鎶涘嚭鏂扮殑InterruptedException();//灏濊瘯鑾峰彇璧勬簮if(!tryAcquire(arg))//璋冪敤鍙互涓柇鐨凙QS鏂规硶doAcquireInterruptibly(arg);}杩欎釜鏂规硶鍜宭ock()鏂规硶绫讳技锛屽彧鏄細涓柇鍝嶅簲锛屽綋褰撳墠绾跨▼璋冪敤璇ユ柟娉曪紝濡傛灉鍏朵粬绾跨▼璋冪敤褰撳墠绾跨▼鐨刬nterrupt()鏂规硶锛屽綋鍓嶇嚎绋嬪皢鎶涘嚭InterruptedException寮傚父銆俠ooleantryLock()publicbooleantryLock(){returnsync.nonfairTryAcquire(1);}finalbooleannonfairTryAcquire(intacquires){finalThreadcurrent=Thread.currentThread();}intc=getState();濡傛灉锛坈==0锛墈濡傛灉锛坈ompareAndSetState锛?锛岃幏鍙栵級锛墈setExclusiveOwnerThread锛堝綋鍓嶏級锛涜繑鍥炵湡锛泒}elseif(current==getExclusiveOwnerThread()){intnextc=c+acquires;if(nextc<0)//婧㈠嚭thrownewError("Maximumlockcountexceeded");璁剧疆鐘舵€侊紙涓嬩竴姝ワ級锛涜繑鍥炵湡锛泒returnfalse;}璇ユ柟娉曞皾璇曡幏鍙栭攣锛屽鏋滃綋鍓嶉攣娌℃湁琚叾浠栫嚎绋嬫寔鏈夛紝鍒欏綋鍓嶇嚎绋嬭幏鍙栭攣骞惰繑鍥瀟rue锛屽惁鍒欒繑鍥瀎alse銆傪煋㈡敞鎰忥細璇ユ柟娉曚笉浼氬鑷村綋鍓嶇嚎绋嬮樆濉炪€俠ooleantryLock(longtimeout,TimeUnitunit)publicbooleantryLock(longtimeout,TimeUnitunit)throwsInterruptedException{returnsync.tryAcquireNanos(1,unit.toNanos(timeout));}涓巘ryLock鐨勫尯鍒湪浜庤缃簡瓒呮椂鏃堕棿锛屽鏋滆秴鏃跺悗杩樻病鏈夎幏鍙栧埌閿侊紝鍒欒繑鍥瀎alse銆傞噴鏀鹃攣voidunlock()publicvoidunlock(){sync.release(1);}publicfinalbooleanrelease(intarg){if(tryRelease(arg)){Nodeh=head;濡傛灉(h!=null&&h.waitStatus!=0)unparkSuccessor(h);杩斿洖鐪燂紱}returnfalse;}protectedfinalbooleantryRelease(intreleases){intc=getState()-releases;寮傚父if(Thread.currentThread()!=getExclusiveOwnerThread())thrownewIllegalMonitorStateException();甯冨皵鑷敱=鍋囷紱//濡傛灉褰撳墠閲嶅叆娆℃暟涓?锛屽垯绾跨▼琚攣瀹歩f(c==0){free=true;setExclusiveOwnerThread(null);}璁剧疆鐘舵€侊紙c锛夛紱returnfree;}璇ユ柟娉曢鍏堝皾璇曢噴鏀鹃攣锛屽鏋渢ryRelease()鏂规硶杩斿洖true锛屽垯閲婃斁閿侊紝鍚﹀垯鍙噺1锛屽鏋滀笉鏄攣鎸佹湁鑰呰皟鐢╱nlock鎶涘嚭IllegalMonitorStateException銆備唬鐮佸疄璺?***@浣滆€呯绉樻澃鍏?鍏紬鍙凤細Java鑿滈笩绋嬪簭鍛?@date2022/1/21*@Description浣跨敤ReentrantLock瀹炵幇涓€涓畝鍗曠殑绾跨▼瀹夊叏鐨凩ist*/publicclassReentrantLockList{privateListarray=newArrayList<>();privatevolatileReentrantLocklock=newReentrantLock();publicvoidadd(Stringe){lock.lock();璇曡瘯{array.add(e);}鏈€鍚巤lock.unlock();}}publicvoidremove(Stringe){閿併€傞攣锛堬級;灏濊瘯{鏁扮粍銆傚垹闄わ紙e锛夛紱}鏈€鍚巤閿併€傚紑閿侊紙锛?}}publicStringget(intindex){閿併€傞攣锛堬級;灏濊瘯{杩斿洖array.get(index);}鏈€鍚巤lock.unlock();}}}鍦ㄦ搷浣滄暟缁勪箣鍓嶏紝璇ョ被浣跨敤閿佹潵淇濊瘉鍚屼竴鏃跺埢鍙湁涓€涓嚎绋嬪彲浠ユ搷浣滄暟缁勶紝浣嗘槸鍙兘鏈変竴涓嚎绋嬪彲浠ヨ闂暟缁勫厓绱犮€傛€荤粨褰撲笁涓嚎绋嬪悓鏃跺皾璇曡幏鍙栨帓浠栭攣ReentrantLock鏃讹紝濡傛灉绾跨▼1鑾峰彇鍒颁簡锛岀嚎绋?鍜岀嚎绋?浼氳浆鍖栦负Node鑺傜偣锛岀劧鍚庢斁鍏eentrantLock瀵瑰簲鐨凙QS闃诲闃熷垪涓紝鐒跺悗鎸傝捣銆傚亣璁剧嚎绋?鑾峰緱閿佸悗锛岃皟鐢ㄩ攣鍒涘缓鐨勬潯浠跺彉閲?锛岃繘鍏wait鍚庯紝绾跨▼1浼氶噴鏀鹃攣銆傜劧鍚庣嚎绋?浼氳浆鍖栦负Node鑺傜偣锛屾彃鍏ュ埌鏉′欢鍙橀噺1鐨勬潯浠堕槦鍒椾腑銆傜敱浜庣嚎绋?閲婃斁浜嗛攣锛岄樆濉為槦鍒椾腑鐨勭嚎绋?鍜岀嚎绋?灏辨湁鏈轰細鑾峰彇鍒伴攣銆傚鏋滀娇鐢ㄥ叕骞抽攣锛岀嚎绋?浼氳幏鍙栭攣锛岀劧鍚庝粠AQS闃诲闃熷垪涓Щ闄ょ嚎绋?瀵瑰簲鐨凬ode鑺傜偣銆?/p>

最新推荐
猜你喜欢