闈㈢粡鎵嬪唽 路 绗?8绡囥€夾QS 鍏变韩閿侊紝Semaphore銆丆ountDownLatch锛屽惉璇存暟鎹簱杩炴帴姹犲彲浠ョ敤鍒帮紒銆?/h1> Posted bugstack铏礊鏍?/a>
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了闈㈢粡鎵嬪唽 路 绗?8绡囥€夾QS 鍏变韩閿侊紝Semaphore銆丆ountDownLatch锛屽惉璇存暟鎹簱杩炴帴姹犲彲浠ョ敤鍒帮紒銆?/h1>
鎸佺画鍧氭寔鍘熷垱杈撳嚭锛岀偣鍑昏摑瀛楀叧娉ㄦ垜鍚?/span>
鉂?/span>
娌夋穩銆佸垎浜€佹垚闀匡紝璁╄嚜宸卞拰浠栦汉閮借兘鏈夋墍鏀惰幏锛侌煒?/p>
鉂?/span>
鐩綍
涓€銆佸墠瑷€
浜屻€侀潰璇曢
涓夈€佸叡浜攣 鍜?AQS
1. 鍩轰簬 AQS 瀹炵幇鐨勯攣鏈夊摢浜涳紵
2. Semaphore 鍏变韩閿佷娇鐢?/p>
3. Semaphore 婧愮爜鍒嗘瀽
4. CountDownLatch 鍏变韩閿佷娇鐢?/p>
鍥涖€佹€荤粨
浜斻€佺郴鍒楁帹鑽?/p>
涓€銆佸墠瑷€
瀛ava鎬庝箞鑳斤紝绐侀鐚涜繘鐨勬垚闀匡紵
鏄笉鏄綘鐪嬭杩囩殑绐侀鐚涜繘閮芥槸鍒汉锛屼絾鑷繁鍗村緢闅撅紒
鍏跺疄骞舵病鏈変竴澶╃殑绐侀鐚涜繘锛屼篃娌℃湁涓€鍙e悆鍑烘潵鐨勮儢瀛愩€傛湁寰楁洿澶氱殑鏃跺€欐棩绉湀绱€佷笉鏂矇娣€锛屾渶鍚庢墠鑳界垎鍙戙€佺牬灞€锛?/p>
涓句釜绠€鍗曠殑渚嬪瓙锛屽鏋滀綘澶у姣曚笟鏃跺€欏凡缁忓啓浜?0涓囪浠g爜锛岃繕鎵句笉鍒板伐浣滃悧锛熶絾40涓囪骞冲潎鍒版瘡澶╁苟涓嶄細寰堝锛岄噸瑕佺殑鏄寔涔嬩互鎭掔殑鍧氭寔銆?/p>
浜屻€侀潰璇曢
璋㈤鏈猴紝灏忚锛?/code> 涓滈鍚广€佹垬榧撴搨锛屼笉鍔犵彮銆佽皝鎬曡皝锛佸搱鍝堝搱锛屾壘鎴戝ぇ鍝ュ幓銆?/p>
銆岃阿椋炴満銆?/strong>锛氬杺锛屽ぇ鍝ャ€傛垜濂冲弸闈㈣瘯鍗′綇浜嗭紝寮轰汉閿?/code>闅撅紝閿佹垜涔熶笉浼氾紒
銆岄潰璇曞畼銆?/strong>锛氫綘涓嶅簲璇ヤ笉浼氬憖锛岄棶浣犱竴涓紝鍩轰簬 AQS 瀹炵幇鐨勯攣閮芥湁鍝簺锛?/p>
銆岃阿椋炴満銆?/strong>锛氬棷锛屾湁 ReentrantLock...
銆岄潰璇曞畼銆?/strong>锛氳繕鏈夊憿锛?/p>
銆岃阿椋炴満銆?/strong>锛氬ソ鍍忔兂涓嶈捣鏉ヤ簡锛宻ync涔熶笉鏄紒
銆岄潰璇曞畼銆?/strong>锛氬搸锛屽鐐规紡鐐癸紝涓嶆€濊€冦€佷笉鎬荤粨銆佷笉璁板綍銆備綘杩欐牱浜哄闈㈣瘯浣犲氨娌℃硶鑱婁簡锛屾渶璧风爜浣犺鏈夌偣娣卞害銆?/p>
銆岃阿椋炴満銆?/strong>锛氬樋鍢匡紝璁颁綇浜嗐€傛潵鎴戝鍚冪伀閿呭惂锛岀粏鑱娿€?/p>
涓夈€佸叡浜攣 鍜?AQS
1. 鍩轰簬 AQS 瀹炵幇鐨勯攣鏈夊摢浜涳紵
AQS锛圓bstractQueuedSynchronizer锛夛紝鏄?Java 骞跺彂鍖呬腑闈炲父閲嶈鐨勪竴涓被锛屽ぇ閮ㄥ垎閿佺殑瀹炵幇涔熸槸鍩轰簬 AQS 瀹炵幇鐨勶紝鍖呮嫭锛?/p>
-
ReentrantLock
锛屽彲閲嶅叆閿併€傝繖涓槸鎴戜滑鏈€寮€濮嬩粙缁嶇殑閿侊紝涔熸槸鏈€甯哥敤鐨勯攣銆傞€氬父浼氫笌 synchronized 鍋氭瘮杈冧娇鐢ㄣ€?
-
ReentrantReadWriteLock
锛岃鍐欓攣銆傝閿佹槸鍏变韩閿併€佸啓閿佹槸鐙崰閿併€?
-
Semaphore
锛屼俊鍙烽噺閿併€備富瑕佺敤浜庢帶鍒舵祦閲忥紝姣斿锛氭暟鎹簱杩炴帴姹犵粰浣犲垎閰?0涓摼鎺ワ紝閭d箞璁╀綘鏉ヤ竴涓繛涓€涓紝杩炲埌10涓繕娌℃湁浜洪噴鏀撅紝閭d綘灏辩瓑绛夈€?
-
CountDownLatch
锛岄棴閿併€侺atch 闂ㄩ棭鐨勬剰鎬濓紝姣斿锛氳鍥涗釜浜轰竴涓紓娴佽墖锛屽潗婊′簡灏辨帹涓嬫按銆?
杩欎竴绔犺妭鎴戜滑涓昏鏉ヤ粙缁?Semaphore 锛屼俊鍙烽噺閿佺殑瀹炵幇锛屽叾瀹炰篃灏辨槸浠嬬粛涓€涓叧浜庡叡浜攣鐨勪娇鐢ㄥ拰婧愮爜鍒嗘瀽銆?/p>
2. Semaphore 鍏变韩閿佷娇鐢?/span>
Semaphore semaphore = new Semaphore(2, false); // 鏋勯€犲嚱鏁板叆鍙傦紝permits锛氫俊鍙烽噺銆乫air锛氬叕骞抽攣/闈炲叕骞抽攣
for (int i = 0; i < 8; i++) {
new Thread(() -> {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + "韫插潙");
Thread.sleep(1000L);
} catch (InterruptedException ignore) {
} finally {
semaphore.release();
}
}, "韫插潙缂栧彿锛? + i).start();
}
杩欓噷鎴戜滑妯℃嫙浜嗕竴涓湪楂橀€熸湇鍔″尯锛屽帟鎵€鎺掗槦韫插潙鐨勫満鏅€傜敱浜庡潙浣嶆湁闄愶紝涓轰簡閬垮厤閫犳垚鎷ユ尋鍜岃俯韪忥紝淇濆畨浜哄憳鍦ㄩ棬鍙f嫤鐫€锛屾劅瑙夊樊涓嶅锛屼竴娆¢噴鏀句袱涓繘鍘伙紝涓€鐩村埌閮介噴鏀俱€?span class="mq-98">浣犱篃鍙互鎯虫垚鏃╀笂鍧愬湴閾佷笂鐝紝鎴栬€呮椇瀛e幓鍏洯锛岄兘鏄竴鎵逛竴鎵圭殑鏀捐
銆屾祴璇曠粨鏋溿€?/strong>
韫插潙缂栧彿锛?span class="mq-104">0
韫插潙
韫插潙缂栧彿锛?span class="mq-105">1
韫插潙
韫插潙缂栧彿锛?span class="mq-106">2
韫插潙
韫插潙缂栧彿锛?span class="mq-107">3韫插潙
韫插潙缂栧彿锛?span class="mq-108">4韫插潙
韫插潙缂栧彿锛?span class="mq-109">5韫插潙
韫插潙缂栧彿锛?span class="mq-110">6韫插潙
韫插潙缂栧彿锛?span class="mq-111">7韫插潙
Process finished with exit code 0
-
Semaphore 鐨勬瀯閫犲嚱鏁板彲浠ヤ紶閫掓槸鍏钩閿佽繕鏄潪鍏钩閿侊紝鏈€缁堢殑娴嬭瘯缁撴灉涔熶笉鍚岋紝鍙互鑷灏濊瘯銆?
-
娴嬭瘯杩愯鏃讹紝浼氬厛杈撳嚭
0鍧戙€?鍧?/code>锛?
涔嬪悗2鍧戙€?鍧?/code>...锛屾瘡娆¢兘鏄繖鏍蜂袱涓紝涓や釜鐨勯噴鏀俱€傝繖灏辨槸 Semaphore 淇″彿閲忛攣鐨勪綔鐢ㄣ€?
3. Semaphore 婧愮爜鍒嗘瀽
3.1 鏋勯€犲嚱鏁?/span>
public Semaphore(int permits) {
sync = new NonfairSync(permits);
}
public Semaphore(int permits, boolean fair) {
sync = fair ? new FairSync(permits) : new NonfairSync(permits);
}
permits锛歯. 璁稿彲璇侊紝鐗硅璇?灏ゆ寚闄愭湡鐨?
榛樿鎯呭喌涓嬪彧闇€瑕佷紶鍏?permits 璁稿彲璇佹暟閲忓嵆鍙紝涔熷氨鏄竴娆″厑璁告斁琛屽嚑涓嚎绋嬨€傛瀯閫犲嚱鏁颁細鍒涘缓闈炲叕骞抽攣銆傚鏋滀綘闇€瑕佷娇鐢?Semaphore 鍏变韩閿佷腑鐨勫叕骞抽攣锛岄偅涔堝彲浠ヤ紶鍏ョ浜屼釜鏋勯€犲嚱鏁扮殑鍙傛暟 fair = false/true銆倀rue锛欶airSync锛屽叕骞抽攣銆?span class="mq-148">鍦ㄦ垜浠墠闈㈢殑绔犺妭宸茬粡浠嬬粛浜嗗叕骞抽攣鐩稿叧鍐呭鍜屽疄鐜帮紝浠ュ強CLH銆丮CS 銆婂叕骞抽攣浠嬬粛銆?/p>
銆屽垵濮?code class="mq-151">璁稿彲璇?/code>鏁伴噺銆?/strong>
FairSync/NonfairSync(int permits) {
super(permits);
}
Sync(int permits) {
setState(permits);
}
protected final void setState(int newState) {
state = newState;
}
鍦ㄦ瀯閫犲嚱鏁板垵濮嬪寲鐨勬椂鍊欙紝鏃犺鏄叕骞抽攣杩樻槸闈炲叕骞抽攣锛岄兘浼氳缃?AQS 涓?state 鏁伴噺鍊笺€傝繖涓€间篃灏辨槸涓轰簡涓嬫枃涓彲浠ヨ幏鍙栫殑淇″彿閲忔墸鍑忓拰澧炲姞鐨勫€笺€?/p>
3.2 acquire 鑾峰彇淇″彿閲?/span>
鏂规硶
鎻忚堪
semaphore.acquire()
涓€娆¤幏鍙栦竴涓俊鍙烽噺锛屽搷搴斾腑鏂?/td>
semaphore.acquire(2)
涓€娆¤幏鍙杗涓俊鍙烽噺锛屽搷搴斾腑鏂紙涓€娆″崰2涓潙锛?/td>
semaphore.acquireUninterruptibly()
涓€娆¤幏鍙栦竴涓俊鍙烽噺锛屼笉鍝嶅簲涓柇
semaphore.acquireUninterruptibly(2)
涓€娆¤幏鍙杗涓俊鍙烽噺锛屼笉鍝嶅簲涓柇
-
鍏跺疄鑾峰彇淇″彿閲忕殑杩欏洓涓柟娉曪紝涓昏灏辨槸锛屼竴娆¤幏鍙栧嚑涓拰鏄惁鍝嶅簲涓柇鐨勭粍鍚堛€?
-
semaphore.acquire()
锛屾簮鐮佷腑瀹為檯璋冪敤鐨勬柟娉曟槸锛?
sync.acquireSharedInterruptibly(1)
銆備篃灏辨槸鐩稿簲涓柇锛屼竴娆″彧鍗犱竴涓潙銆?
-
semaphore.acquire(2)
锛屽悓鐞嗚繖涓氨鏄竴娆¤鍗犱袱涓悕棰濓紝涔熷氨鏄鍙瘉銆?
鐢熸椿涓殑鍦烘櫙灏辨槸鎴戠粰鎴戞湅鍙嬫帓鐨勫锛屽ス鏉ヤ簡锛岃繘鏉ュ惂銆?/span>
3.3 acquire 閲婃斁淇″彿閲?/span>
鏂规硶
鎻忚堪
semaphore.release()
涓€娆¢噴鏀句竴涓俊鍙烽噺
semaphore.release(2)
涓€娆¤幏鍙杗涓俊鍙烽噺
鏈夎幏鍙栧氨寰楁湁閲婃斁锛岃幏鍙栦簡鍑犱釜淇″彿閲忓氨瑕侀噴鏀惧嚑涓俊鍙烽噺銆?span class="mq-213">褰撶劧浣犲彲浠ュ皾璇曚竴涓嬶紝鑾峰彇淇″彿閲?semaphore.acquire(2) 涓や釜锛岄噴鏀句俊鍙烽噺 semaphore.release(1)锛岀湅鐪嬭繍琛屾晥鏋?/span>
3.4 鍏钩閿佸疄鐜?/span>
銆屼俊鍙烽噺鑾峰彇杩囩▼銆?/strong>锛屼竴鐩村埌鍏钩閿佸疄鐜般€?code class="mq-221">semaphore.acquire -> sync.acquireSharedInterruptibly(permits)
-> tryAcquireShared(arg)
semaphore.acquire(1);
public void acquire(int permits) throws InterruptedException {
if (permits < 0) throw new IllegalArgumentException();
sync.acquireSharedInterruptibly(permits);
}
public final void acquireSharedInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (tryAcquireShared(arg) < 0)
doAcquireSharedInterruptibly(arg);
}
銆孎airSync.tryAcquireShared銆?/strong>
protected int tryAcquireShared(int acquires) {
for (;;) {
if (hasQueuedPredecessors())
return -1;
int available = getState();
int remaining = available - acquires;
if (remaining < 0 ||
compareAndSetState(available, remaining))
return remaining;
}
}
-
hasQueuedPredecessors
锛屽叕骞抽攣鐨勪富瑕佸疄鐜伴€昏緫閮藉湪浜庤繖涓柟娉曠殑浣跨敤銆傚畠鐨勭洰鐨勫氨鏄垽鏂湁绾跨▼鎺掑湪鑷繁鍓嶉潰娌★紝浠ュ強鎶婄嚎绋嬫坊鍔犲埌闃熷垪涓殑閫昏緫瀹炵幇銆?
鍦ㄥ墠闈㈡垜浠粙缁嶈繃CLH绛夊疄鐜帮紝鍙互寰€鍓嶄竴绔犺妭闃呰
-
for (;;)
锛屾槸涓€涓嚜鏃嬬殑杩囩▼锛岄€氳繃 CAS 鏉ヨ缃?state 鍋忕Щ閲忓搴斿€笺€傝繖鏍峰氨鍙互閬垮厤澶氱嚎绋嬩笅绔炰簤鑾峰彇淇″彿閲忓啿绐併€?
-
getState()
锛屽湪鏋勯€犲嚱鏁颁腑宸茬粡鍒濆鍖?state 鍊硷紝鍦ㄨ繖閲岃幏鍙栦俊鍙烽噺鏃跺氨鏄娇鐢?CAS 涓嶆柇鐨勬墸鍑忋€?
-
鍙﹀闇€瑕佹敞鎰忥紝鍏变韩閿佸拰鐙崰閿佸湪杩欓噷鏄湁鍖哄埆鐨勶紝鐙崰閿佺洿鎺ヨ繑鍥瀟rue/false锛屽叡浜攣杩斿洖鐨勬槸int鍊笺€?
-
濡傛灉璇ュ€煎皬浜?锛屽垯褰撳墠绾跨▼鑾峰彇鍏变韩閿佸け璐ャ€?
-
濡傛灉璇ュ€煎ぇ浜?锛屽垯褰撳墠绾跨▼鑾峰彇鍏变韩閿佹垚鍔燂紝骞朵笖鎺ヤ笅鏉ュ叾浠栫嚎绋嬪皾璇曡幏鍙栧叡浜攣鐨勮涓哄緢鍙兘鎴愬姛銆?
-
濡傛灉璇ュ€肩瓑浜?锛屽垯褰撳墠绾跨▼鑾峰彇鍏变韩閿佹垚鍔燂紝浣嗘槸鎺ヤ笅鏉ュ叾浠栫嚎绋嬪皾璇曡幏鍙栧叡浜攣鐨勮涓轰細澶辫触銆?
3.5 闈炲叕骞抽攣瀹炵幇
銆孨onfairSync.nonfairTryAcquireShared銆?/strong>
protected int tryAcquireShared(int acquires) {
return nonfairTryAcquireShared(acquires);
}
final int nonfairTryAcquireShared(int acquires) {
for (;;) {
int available = getState();
int remaining = available - acquires;
if (remaining < 0 ||
compareAndSetState(available, remaining))
return remaining;
}
}
-
鏈変簡鍏钩閿佺殑瀹炵幇锛岄潪鍏钩閿佺殑鐞嗚В灏辨瘮杈冪畝鍗曚簡锛屽彧鏄嬁鍘讳簡
if (hasQueuedPredecessors())
鐨勫垽鏂搷浣溿€?
-
鍏朵粬鐨勯€昏緫瀹炵幇閮藉拰鍏钩閿佷竴鑷淬€?
3.6 鑾峰彇淇″彿閲忓け璐ワ紝鍔犲叆鍚屾绛夊緟闃熷垪
鍦ㄥ叕骞抽攣鍜岄潪鍏钩閿佺殑瀹炵幇涓紝鎴戜滑宸茬粡鐪嬪埌姝e父鑾峰彇淇″彿閲忕殑閫昏緫銆傞偅涔堝鏋滄鏃朵笉鑳芥甯歌幏鍙栦俊鍙烽噺鍛紵鍏跺疄杩欓儴鍒嗙嚎绋嬪氨闇€瑕佸姞鍏ュ埌鍚屾闃熷垪銆?/p>
銆宒oAcquireSharedInterruptibly銆?/strong>
public final void acquireSharedInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (tryAcquireShared(arg) < 0)
doAcquireSharedInterruptibly(arg);
}
private void doAcquireSharedInterruptibly(int arg)
throws InterruptedException {
final Node node = addWaiter(Node.SHARED);
boolean failed = true;
try {
for (;;) {
final Node p = node.predecessor();
if (p == head) {
int r = tryAcquireShared(arg);
if (r >= 0) {
setHeadAndPropagate(node, r);
p.next = null; // help GC
failed = false;
return;
}
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
throw new InterruptedException();
}
} finally {
if (failed)
cancelAcquire(node);
}
}
-
棣栧厛
doAcquireSharedInterruptibly
鏂规硶鏉ヨ嚜 AQS 鐨勫唴閮ㄦ柟娉曪紝涓庢垜浠湪瀛︿範绔炰簤閿佹椂鏈夐儴鍒嗙煡璇嗙偣鐩稿悓锛屼絾涔熸湁涓€浜涘樊寮傘€傛瘮濡傦細
addWaiter(Node.SHARED)
锛?
tryAcquireShared
锛屾垜浠富瑕佷粙缁嶄笅杩欏唴瀹广€?
-
Node.SHARED
锛屽叾瀹炴病鏈夌壒娈婂惈涔夛紝瀹冨彧鏄竴涓爣璁颁綔鐢紝鐢ㄤ簬鍒ゆ柇鏄惁鍏变韩銆?
final boolean isShared() { return nextWaiter == SHARED; }
-
tryAcquireShared
锛屼富瑕佹槸鏉ヨ嚜
Semaphore
鍏变韩閿佷腑鍏钩閿佸拰闈炲叕骞抽攣鐨勫疄鐜般€傜敤鏉ヨ幏鍙栧悓姝ョ姸鎬併€?
-
setHeadAndPropagate(node, r)
锛屽鏋渞 > 0锛屽悓姝ユ垚鍔熷悗鍒欏皢褰撳墠绾跨▼缁撶偣璁剧疆涓哄ご缁撶偣锛屽悓鏃?helpGC锛宲.next = null锛屾柇閾炬搷浣溿€?
-
shouldParkAfterFailedAcquire(p, node)
锛岃皟鏁村悓姝ラ槦鍒椾腑 node 缁撶偣鐨勭姸鎬侊紝骞跺垽鏂槸鍚﹀簲璇ヨ鎸傝捣銆傝繖鍦ㄦ垜浠箣鍓嶅叧浜庨攣鐨勬枃绔犱腑宸茬粡浠嬬粛銆?
-
parkAndCheckInterrupt()
锛屽垽鏂槸鍚﹂渶瑕佽涓柇锛屽鏋滀腑鏂洿鎺ユ姏鍑哄紓甯革紝褰撳墠缁撶偣璇锋眰涔熷氨缁撴潫銆?
-
cancelAcquire(node)
锛屽彇娑堣鑺傜偣鐨勭嚎绋嬭姹傘€?
4. CountDownLatch 鍏变韩閿佷娇鐢?/span>
CountDownLatch 涔熸槸鍏变韩閿佺殑涓€绉嶇被鍨嬶紝涔嬫墍浠ュ湪杩欓噷浣撶幇涓嬶紝鏄洜涓哄畠鍜?Semaphore 鍏变韩閿侊紝鏃㈢浉浼兼湁涓嶅悓銆?/p>
CountDownLatch 鏇村浣撶幇鐨勭粍鍥竴娉㈢殑鎬濇兂锛屽悓鏍锋槸鎺у埗浜烘暟锛屼絾鏄渶瑕佸涓€绐濄€傛瘮濡傦細鎴戜滑璇磋繃鐨?涓汉涓€璧蜂笂鐨垝鑹囥€佷袱涓汉涓€璧蜂笂璺疯贩鏉裤€?span class="mq-394">2涓汉涓€璧疯共鍧戞垜娌¤杩?/span>锛岃繖鏍风殑鏂瑰紡灏辨槸闂ㄩ棭 CountDownLatch 閿佺殑鎬濇兂銆?/p>
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(10);
ExecutorService exec = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
exec.execute(() -> {
try {
int millis = new Random().nextInt(10000);
System.out.println("绛夊緟娓稿涓婅埞锛岃€楁椂锛? + millis + "(millis)");
Thread.sleep(millis);
} catch (Exception ignore) {
} finally {
latch.countDown(); // 瀹屼簨涓€涓墸鍑忎竴涓悕棰?/span>
}
});
}
// 绛夊緟娓稿
latch.await();
System.out.println("鑸归暱鎬ヨ簛浜嗭紝寮€鑸?");
// 鍏抽棴绾跨▼姹?/span>
exec.shutdown();
}
-
杩欎竴涓叕鍥父鑸圭殑鍦烘櫙妗堜緥锛岀瓑寰?0涓箻瀹笂浼狅紝浠栦滑姣旇緝澧ㄨ抗銆?
-
涓婁竴涓墸鍑忎竴涓?
latch.countDown()
-
绛夊緟娓稿閮戒笂鑸?
latch.await()
-
鏈€鍚庤埞闀垮紑鑸癸紒锛?
鎬ヨ簛浜?/code>
銆屾祴璇曠粨鏋溿€?/strong>
绛夊緟娓稿涓婅埞锛岃€楁椂锛?span class="mq-437">6689(millis)
绛夊緟娓稿涓婅埞锛岃€楁椂锛?span class="mq-438">2303(millis)
绛夊緟娓稿涓婅埞锛岃€楁椂锛?span class="mq-439">8208(millis)
绛夊緟娓稿涓婅埞锛岃€楁椂锛?span class="mq-440">435(millis)
绛夊緟娓稿涓婅埞锛岃€楁椂锛?span class="mq-441">9489(millis)
绛夊緟娓稿涓婅埞锛岃€楁椂锛?span class="mq-442">4937(millis)
绛夊緟娓稿涓婅埞锛岃€楁椂锛?span class="mq-443">2771(millis)
绛夊緟娓稿涓婅埞锛岃€楁椂锛?span class="mq-444">4823(millis)
绛夊緟娓稿涓婅埞锛岃€楁椂锛?span class="mq-445">1989(millis)
绛夊緟娓稿涓婅埞锛岃€楁椂锛?span class="mq-446">8506(millis)
鑸归暱鎬ヨ簛浜嗭紝寮€鑸?
Process finished with exit code 0
-
鍦ㄤ綘瀹為檯鐨勬祴璇曚腑浼氬彂鐜帮紝
鑸归暱鎬ヨ簛浜嗭紝寮€鑸?
锛屼細闇€瑕佺瓑寰呬竴娈垫椂闂淬€?
-
杩欓噷浣撶幇鐨勫氨鏄棬闂╃殑鎬濇兂锛岀粍闃熴€佷竴娉㈠甫璧般€?
-
CountDownLatch 鐨勫疄鐜颁笌 Semaphore 鍩烘湰鐩稿悓銆佺粏鑺傜暐鏈夊樊寮傦紝灏变笉鍐嶅仛婧愮爜鍒嗘瀽浜嗐€?
鍥涖€佹€荤粨
-
鍦ㄦ湁浜?AQS銆丆LH銆丮CS锛岀瓑鐩稿叧閿佺殑鐭ヨ瘑浜嗚В鍚庯紝鍦ㄥ涔犲叾浠栫煡璇嗙偣涔熺浉瀵瑰鏄撱€傚熀鏈互涓婂拰鍓嶅嚑绔犺妭鍏充簬閿佺殑浠嬬粛锛屼篃鏄潰璇曚腑瀹规槗闂埌鐨勭偣銆?
鍙兘鐢变簬鐩墠鍒嗗竷寮忓紑鍙戣緝澶氾紝鍗曟満鐨勫绾跨▼鎬ц兘鍘嬫Θ涓€鑸緝灏戯紝浣嗘槸瀵硅繖閮ㄥ垎鐭ヨ瘑鐨勪簡瑙i潪甯搁噸瑕?/span>
-
寰楃泭浜嶭ee鑰佺埛瀛愮殑鎿嶅垁锛屽苟鍙戝寘閿佺殑璁捐鐪熺殑闈炲父浼樼銆傛瘡涓€澶勭殑瀹炵幇閮藉彲浠ヨ鏄簿鐩婃眰绮撅紝鎵€浠ュ湪瀛︿範鐨勬椂鍊欏彲浠ユ妸灏忓倕鍝ョ殑鏂囩珷褰撲綔鎶涚爾锛屼箣鍚庣户缁繁鎸栬璁$簿楂擄紝涓嶆柇娣卞叆銆?
-
鍏变韩閿佺殑浣跨敤鍙兘骞虫椂骞朵笉澶氾紝浣嗗鏋滀綘闇€瑕佽璁′竴娆剧被浼兼暟鎹簱绾跨▼姹犵殑璁捐锛岄偅涔堣繖鏍风殑淇″彿閲忛攣鐨勬€濇兂灏遍潪甯搁噸瑕佷簡銆傛墍浠ュ湪瀛︿範鐨勬椂鍊欎篃闇€瑕佹湁鎶€鏈縼绉荤殑鑳斤紝涓嶆柇鎶婅繖浜涚煡璇嗗鐢ㄥ埌瀹為檯鐨勪笟鍔″紑鍙戜腑銆?
浜斻€佺郴鍒楁帹鑽?/span>
-
-
-
-
-
bugstack铏礊鏍?/strong>
娌夋穩銆佸垎浜€佹垚闀匡紝璁╄嚜宸卞拰浠栦汉閮借兘鏈夋墍鏀惰幏锛?/span>
浣滆€呭皬鍌呭摜澶氬勾浠庝簨涓€绾夸簰鑱旂綉Java
寮€鍙戯紝浠?9骞村紑濮嬬紪鍐欏伐浣滃拰瀛︿範鍘嗙▼鐨勬妧鏈眹鎬伙紝鏃ㄥ湪涓哄ぇ瀹舵彁渚涗竴涓緝娓呮櫚璇︾粏鐨勬牳蹇冩妧鑳藉涔犳枃妗c€傚鏋滄湰鏂囪兘涓烘偍鎻愪緵甯姪锛岃缁欎簣鏀寔(鍏虫敞銆佺偣璧炪€佸垎浜?锛?img data-ratio="1" src="/img?url=https://mmbiz.qpic.cn/sz_mmbiz_png/zTfAIs5rNXjk2CsH6SOUSmNNRmT72WHVIQdSibib4TDkwIHev4eWfyCYBsZz5xG88W6Qy6a69iaemCoxVezmgtl1Q/640?wx_fmt=png" data-type="png" data-w="20" _width="20px" alt="闈㈢粡鎵嬪唽 路 绗?8绡囥€夾QS 鍏变韩閿侊紝Semaphore銆丆ountDownLatch锛屽惉璇存暟鎹簱杩炴帴姹犲彲浠ョ敤鍒帮紒銆? class="mq-483">
鎰熻阿鏀寔灏忓倕鍝ュ師鍒涳紝娆㈣繋鐐瑰嚮鍦ㄧ湅鍜?/span>杞彂
以上是关于闈㈢粡鎵嬪唽 路 绗?8绡囥€夾QS 鍏变韩閿侊紝Semaphore銆丆ountDownLatch锛屽惉璇存暟鎹簱杩炴帴姹犲彲浠ョ敤鍒帮紒銆?/h1>
Posted bugstack铏礊鏍?/a>
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了闈㈢粡鎵嬪唽 路 绗?8绡囥€夾QS 鍏变韩閿侊紝Semaphore銆丆ountDownLatch锛屽惉璇存暟鎹簱杩炴帴姹犲彲浠ョ敤鍒帮紒銆?/h1>
鎸佺画鍧氭寔鍘熷垱杈撳嚭锛岀偣鍑昏摑瀛楀叧娉ㄦ垜鍚?/span>
鉂?/span>娌夋穩銆佸垎浜€佹垚闀匡紝璁╄嚜宸卞拰浠栦汉閮借兘鏈夋墍鏀惰幏锛侌煒?/p> 鉂?/span>
鐩綍
涓€銆佸墠瑷€
浜屻€侀潰璇曢
涓夈€佸叡浜攣 鍜?AQS
1. 鍩轰簬 AQS 瀹炵幇鐨勯攣鏈夊摢浜涳紵
2. Semaphore 鍏变韩閿佷娇鐢?/p>
3. Semaphore 婧愮爜鍒嗘瀽
4. CountDownLatch 鍏变韩閿佷娇鐢?/p>
鍥涖€佹€荤粨
浜斻€佺郴鍒楁帹鑽?/p>
涓€銆佸墠瑷€
瀛ava鎬庝箞鑳斤紝绐侀鐚涜繘鐨勬垚闀匡紵
鏄笉鏄綘鐪嬭杩囩殑绐侀鐚涜繘閮芥槸鍒汉锛屼絾鑷繁鍗村緢闅撅紒
鍏跺疄骞舵病鏈変竴澶╃殑绐侀鐚涜繘锛屼篃娌℃湁涓€鍙e悆鍑烘潵鐨勮儢瀛愩€傛湁寰楁洿澶氱殑鏃跺€欐棩绉湀绱€佷笉鏂矇娣€锛屾渶鍚庢墠鑳界垎鍙戙€佺牬灞€锛?/p>
涓句釜绠€鍗曠殑渚嬪瓙锛屽鏋滀綘澶у姣曚笟鏃跺€欏凡缁忓啓浜?0涓囪浠g爜锛岃繕鎵句笉鍒板伐浣滃悧锛熶絾40涓囪骞冲潎鍒版瘡澶╁苟涓嶄細寰堝锛岄噸瑕佺殑鏄寔涔嬩互鎭掔殑鍧氭寔銆?/p>
浜屻€侀潰璇曢
銆岃阿椋炴満銆?/strong>锛氬杺锛屽ぇ鍝ャ€傛垜濂冲弸闈㈣瘯鍗′綇浜嗭紝寮轰汉 銆岄潰璇曞畼銆?/strong>锛氫綘涓嶅簲璇ヤ笉浼氬憖锛岄棶浣犱竴涓紝鍩轰簬 AQS 瀹炵幇鐨勯攣閮芥湁鍝簺锛?/p>
銆岃阿椋炴満銆?/strong>锛氬棷锛屾湁 ReentrantLock... 銆岄潰璇曞畼銆?/strong>锛氳繕鏈夊憿锛?/p>
銆岃阿椋炴満銆?/strong>锛氬ソ鍍忔兂涓嶈捣鏉ヤ簡锛宻ync涔熶笉鏄紒 銆岄潰璇曞畼銆?/strong>锛氬搸锛屽鐐规紡鐐癸紝涓嶆€濊€冦€佷笉鎬荤粨銆佷笉璁板綍銆備綘杩欐牱浜哄闈㈣瘯浣犲氨娌℃硶鑱婁簡锛屾渶璧风爜浣犺鏈夌偣娣卞害銆?/p>
銆岃阿椋炴満銆?/strong>锛氬樋鍢匡紝璁颁綇浜嗐€傛潵鎴戝鍚冪伀閿呭惂锛岀粏鑱娿€?/p>
AQS锛圓bstractQueuedSynchronizer锛夛紝鏄?Java 骞跺彂鍖呬腑闈炲父閲嶈鐨勪竴涓被锛屽ぇ閮ㄥ垎閿佺殑瀹炵幇涔熸槸鍩轰簬 AQS 瀹炵幇鐨勶紝鍖呮嫭锛?/p>
杩欎竴绔犺妭鎴戜滑涓昏鏉ヤ粙缁?Semaphore 锛屼俊鍙烽噺閿佺殑瀹炵幇锛屽叾瀹炰篃灏辨槸浠嬬粛涓€涓叧浜庡叡浜攣鐨勪娇鐢ㄥ拰婧愮爜鍒嗘瀽銆?/p>
杩欓噷鎴戜滑妯℃嫙浜嗕竴涓湪楂橀€熸湇鍔″尯锛屽帟鎵€鎺掗槦韫插潙鐨勫満鏅€傜敱浜庡潙浣嶆湁闄愶紝涓轰簡閬垮厤閫犳垚鎷ユ尋鍜岃俯韪忥紝淇濆畨浜哄憳鍦ㄩ棬鍙f嫤鐫€锛屾劅瑙夊樊涓嶅锛屼竴娆¢噴鏀句袱涓繘鍘伙紝涓€鐩村埌閮介噴鏀俱€?span class="mq-98">浣犱篃鍙互鎯虫垚鏃╀笂鍧愬湴閾佷笂鐝紝鎴栬€呮椇瀛e幓鍏洯锛岄兘鏄竴鎵逛竴鎵圭殑鏀捐 銆屾祴璇曠粨鏋溿€?/strong>璋㈤鏈猴紝灏忚锛?/code> 涓滈鍚广€佹垬榧撴搨锛屼笉鍔犵彮銆佽皝鎬曡皝锛佸搱鍝堝搱锛屾壘鎴戝ぇ鍝ュ幓銆?/p>
閿?/code>闅撅紝閿佹垜涔熶笉浼氾紒
涓夈€佸叡浜攣 鍜?AQS
1. 鍩轰簬 AQS 瀹炵幇鐨勯攣鏈夊摢浜涳紵
ReentrantLock
锛屽彲閲嶅叆閿併€傝繖涓槸鎴戜滑鏈€寮€濮嬩粙缁嶇殑閿侊紝涔熸槸鏈€甯哥敤鐨勯攣銆傞€氬父浼氫笌 synchronized 鍋氭瘮杈冧娇鐢ㄣ€?
ReentrantReadWriteLock
锛岃鍐欓攣銆傝閿佹槸鍏变韩閿併€佸啓閿佹槸鐙崰閿併€?
Semaphore
锛屼俊鍙烽噺閿併€備富瑕佺敤浜庢帶鍒舵祦閲忥紝姣斿锛氭暟鎹簱杩炴帴姹犵粰浣犲垎閰?0涓摼鎺ワ紝閭d箞璁╀綘鏉ヤ竴涓繛涓€涓紝杩炲埌10涓繕娌℃湁浜洪噴鏀撅紝閭d綘灏辩瓑绛夈€?
CountDownLatch
锛岄棴閿併€侺atch 闂ㄩ棭鐨勬剰鎬濓紝姣斿锛氳鍥涗釜浜轰竴涓紓娴佽墖锛屽潗婊′簡灏辨帹涓嬫按銆?
2. Semaphore 鍏变韩閿佷娇鐢?/span>
Semaphore semaphore = new Semaphore(2, false); // 鏋勯€犲嚱鏁板叆鍙傦紝permits锛氫俊鍙烽噺銆乫air锛氬叕骞抽攣/闈炲叕骞抽攣
for (int i = 0; i < 8; i++) {
new Thread(() -> {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + "韫插潙");
Thread.sleep(1000L);
} catch (InterruptedException ignore) {
} finally {
semaphore.release();
}
}, "韫插潙缂栧彿锛? + i).start();
}
韫插潙韫插潙缂栧彿锛?span class="mq-104">0
韫插潙缂栧彿锛?span class="mq-105">1
韫插潙缂栧彿锛?span class="mq-106">2
韫插潙缂栧彿锛?span class="mq-107">3韫插潙
韫插潙缂栧彿锛?span class="mq-108">4韫插潙
韫插潙缂栧彿锛?span class="mq-109">5韫插潙
韫插潙缂栧彿锛?span class="mq-110">6韫插潙
韫插潙缂栧彿锛?span class="mq-111">7韫插潙
Process finished with exit code 0
-
Semaphore 鐨勬瀯閫犲嚱鏁板彲浠ヤ紶閫掓槸鍏钩閿佽繕鏄潪鍏钩閿侊紝鏈€缁堢殑娴嬭瘯缁撴灉涔熶笉鍚岋紝鍙互鑷灏濊瘯銆? -
娴嬭瘯杩愯鏃讹紝浼氬厛杈撳嚭 0鍧戙€?鍧?/code>锛?
涔嬪悗2鍧戙€?鍧?/code>...锛屾瘡娆¢兘鏄繖鏍蜂袱涓紝涓や釜鐨勯噴鏀俱€傝繖灏辨槸 Semaphore 淇″彿閲忛攣鐨勪綔鐢ㄣ€?
3. Semaphore 婧愮爜鍒嗘瀽
3.1 鏋勯€犲嚱鏁?/span>
public Semaphore(int permits) {
sync = new NonfairSync(permits);
}
public Semaphore(int permits, boolean fair) {
sync = fair ? new FairSync(permits) : new NonfairSync(permits);
}
permits锛歯. 璁稿彲璇侊紝鐗硅璇?灏ゆ寚闄愭湡鐨?
榛樿鎯呭喌涓嬪彧闇€瑕佷紶鍏?permits 璁稿彲璇佹暟閲忓嵆鍙紝涔熷氨鏄竴娆″厑璁告斁琛屽嚑涓嚎绋嬨€傛瀯閫犲嚱鏁颁細鍒涘缓闈炲叕骞抽攣銆傚鏋滀綘闇€瑕佷娇鐢?Semaphore 鍏变韩閿佷腑鐨勫叕骞抽攣锛岄偅涔堝彲浠ヤ紶鍏ョ浜屼釜鏋勯€犲嚱鏁扮殑鍙傛暟 fair = false/true銆倀rue锛欶airSync锛屽叕骞抽攣銆?span class="mq-148">鍦ㄦ垜浠墠闈㈢殑绔犺妭宸茬粡浠嬬粛浜嗗叕骞抽攣鐩稿叧鍐呭鍜屽疄鐜帮紝浠ュ強CLH銆丮CS 銆婂叕骞抽攣浠嬬粛銆?/p>
銆屽垵濮?code class="mq-151">璁稿彲璇?/code>鏁伴噺銆?/strong>
FairSync/NonfairSync(int permits) {
super(permits);
}
Sync(int permits) {
setState(permits);
}
protected final void setState(int newState) {
state = newState;
}
鍦ㄦ瀯閫犲嚱鏁板垵濮嬪寲鐨勬椂鍊欙紝鏃犺鏄叕骞抽攣杩樻槸闈炲叕骞抽攣锛岄兘浼氳缃?AQS 涓?state 鏁伴噺鍊笺€傝繖涓€间篃灏辨槸涓轰簡涓嬫枃涓彲浠ヨ幏鍙栫殑淇″彿閲忔墸鍑忓拰澧炲姞鐨勫€笺€?/p>
3.2 acquire 鑾峰彇淇″彿閲?/span>
鏂规硶 | 鎻忚堪 |
---|---|
semaphore.acquire() |
涓€娆¤幏鍙栦竴涓俊鍙烽噺锛屽搷搴斾腑鏂?/td> |
semaphore.acquire(2) |
涓€娆¤幏鍙杗涓俊鍙烽噺锛屽搷搴斾腑鏂紙涓€娆″崰2涓潙锛?/td> |
semaphore.acquireUninterruptibly() |
涓€娆¤幏鍙栦竴涓俊鍙烽噺锛屼笉鍝嶅簲涓柇 |
semaphore.acquireUninterruptibly(2) |
涓€娆¤幏鍙杗涓俊鍙烽噺锛屼笉鍝嶅簲涓柇 |
-
鍏跺疄鑾峰彇淇″彿閲忕殑杩欏洓涓柟娉曪紝涓昏灏辨槸锛屼竴娆¤幏鍙栧嚑涓拰鏄惁鍝嶅簲涓柇鐨勭粍鍚堛€? -
semaphore.acquire()
锛屾簮鐮佷腑瀹為檯璋冪敤鐨勬柟娉曟槸锛?sync.acquireSharedInterruptibly(1)
銆備篃灏辨槸鐩稿簲涓柇锛屼竴娆″彧鍗犱竴涓潙銆? -
semaphore.acquire(2)
锛屽悓鐞嗚繖涓氨鏄竴娆¤鍗犱袱涓悕棰濓紝涔熷氨鏄鍙瘉銆? 鐢熸椿涓殑鍦烘櫙灏辨槸鎴戠粰鎴戞湅鍙嬫帓鐨勫锛屽ス鏉ヤ簡锛岃繘鏉ュ惂銆?/span>
3.3 acquire 閲婃斁淇″彿閲?/span>
鏂规硶 | 鎻忚堪 |
---|---|
semaphore.release() |
涓€娆¢噴鏀句竴涓俊鍙烽噺 |
semaphore.release(2) |
涓€娆¤幏鍙杗涓俊鍙烽噺 |
鏈夎幏鍙栧氨寰楁湁閲婃斁锛岃幏鍙栦簡鍑犱釜淇″彿閲忓氨瑕侀噴鏀惧嚑涓俊鍙烽噺銆?span class="mq-213">褰撶劧浣犲彲浠ュ皾璇曚竴涓嬶紝鑾峰彇淇″彿閲?semaphore.acquire(2) 涓や釜锛岄噴鏀句俊鍙烽噺 semaphore.release(1)锛岀湅鐪嬭繍琛屾晥鏋?/span>
3.4 鍏钩閿佸疄鐜?/span>
銆屼俊鍙烽噺鑾峰彇杩囩▼銆?/strong>锛屼竴鐩村埌鍏钩閿佸疄鐜般€?code class="mq-221">semaphore.acquire -> sync.acquireSharedInterruptibly(permits)
-> tryAcquireShared(arg)
semaphore.acquire(1);
public void acquire(int permits) throws InterruptedException {
if (permits < 0) throw new IllegalArgumentException();
sync.acquireSharedInterruptibly(permits);
}
public final void acquireSharedInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (tryAcquireShared(arg) < 0)
doAcquireSharedInterruptibly(arg);
}
銆孎airSync.tryAcquireShared銆?/strong>
protected int tryAcquireShared(int acquires) {
for (;;) {
if (hasQueuedPredecessors())
return -1;
int available = getState();
int remaining = available - acquires;
if (remaining < 0 ||
compareAndSetState(available, remaining))
return remaining;
}
}
-
hasQueuedPredecessors
锛屽叕骞抽攣鐨勪富瑕佸疄鐜伴€昏緫閮藉湪浜庤繖涓柟娉曠殑浣跨敤銆傚畠鐨勭洰鐨勫氨鏄垽鏂湁绾跨▼鎺掑湪鑷繁鍓嶉潰娌★紝浠ュ強鎶婄嚎绋嬫坊鍔犲埌闃熷垪涓殑閫昏緫瀹炵幇銆? 鍦ㄥ墠闈㈡垜浠粙缁嶈繃CLH绛夊疄鐜帮紝鍙互寰€鍓嶄竴绔犺妭闃呰 -
for (;;)
锛屾槸涓€涓嚜鏃嬬殑杩囩▼锛岄€氳繃 CAS 鏉ヨ缃?state 鍋忕Щ閲忓搴斿€笺€傝繖鏍峰氨鍙互閬垮厤澶氱嚎绋嬩笅绔炰簤鑾峰彇淇″彿閲忓啿绐併€? -
getState()
锛屽湪鏋勯€犲嚱鏁颁腑宸茬粡鍒濆鍖?state 鍊硷紝鍦ㄨ繖閲岃幏鍙栦俊鍙烽噺鏃跺氨鏄娇鐢?CAS 涓嶆柇鐨勬墸鍑忋€? -
鍙﹀闇€瑕佹敞鎰忥紝鍏变韩閿佸拰鐙崰閿佸湪杩欓噷鏄湁鍖哄埆鐨勶紝鐙崰閿佺洿鎺ヨ繑鍥瀟rue/false锛屽叡浜攣杩斿洖鐨勬槸int鍊笺€? -
濡傛灉璇ュ€煎皬浜?锛屽垯褰撳墠绾跨▼鑾峰彇鍏变韩閿佸け璐ャ€? -
濡傛灉璇ュ€煎ぇ浜?锛屽垯褰撳墠绾跨▼鑾峰彇鍏变韩閿佹垚鍔燂紝骞朵笖鎺ヤ笅鏉ュ叾浠栫嚎绋嬪皾璇曡幏鍙栧叡浜攣鐨勮涓哄緢鍙兘鎴愬姛銆? -
濡傛灉璇ュ€肩瓑浜?锛屽垯褰撳墠绾跨▼鑾峰彇鍏变韩閿佹垚鍔燂紝浣嗘槸鎺ヤ笅鏉ュ叾浠栫嚎绋嬪皾璇曡幏鍙栧叡浜攣鐨勮涓轰細澶辫触銆?
3.5 闈炲叕骞抽攣瀹炵幇
銆孨onfairSync.nonfairTryAcquireShared銆?/strong>
protected int tryAcquireShared(int acquires) {
return nonfairTryAcquireShared(acquires);
}
final int nonfairTryAcquireShared(int acquires) {
for (;;) {
int available = getState();
int remaining = available - acquires;
if (remaining < 0 ||
compareAndSetState(available, remaining))
return remaining;
}
}
-
鏈変簡鍏钩閿佺殑瀹炵幇锛岄潪鍏钩閿佺殑鐞嗚В灏辨瘮杈冪畝鍗曚簡锛屽彧鏄嬁鍘讳簡 if (hasQueuedPredecessors())
鐨勫垽鏂搷浣溿€? -
鍏朵粬鐨勯€昏緫瀹炵幇閮藉拰鍏钩閿佷竴鑷淬€?
3.6 鑾峰彇淇″彿閲忓け璐ワ紝鍔犲叆鍚屾绛夊緟闃熷垪
鍦ㄥ叕骞抽攣鍜岄潪鍏钩閿佺殑瀹炵幇涓紝鎴戜滑宸茬粡鐪嬪埌姝e父鑾峰彇淇″彿閲忕殑閫昏緫銆傞偅涔堝鏋滄鏃朵笉鑳芥甯歌幏鍙栦俊鍙烽噺鍛紵鍏跺疄杩欓儴鍒嗙嚎绋嬪氨闇€瑕佸姞鍏ュ埌鍚屾闃熷垪銆?/p>
銆宒oAcquireSharedInterruptibly銆?/strong>
public final void acquireSharedInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (tryAcquireShared(arg) < 0)
doAcquireSharedInterruptibly(arg);
}
private void doAcquireSharedInterruptibly(int arg)
throws InterruptedException {
final Node node = addWaiter(Node.SHARED);
boolean failed = true;
try {
for (;;) {
final Node p = node.predecessor();
if (p == head) {
int r = tryAcquireShared(arg);
if (r >= 0) {
setHeadAndPropagate(node, r);
p.next = null; // help GC
failed = false;
return;
}
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
throw new InterruptedException();
}
} finally {
if (failed)
cancelAcquire(node);
}
}
-
棣栧厛 doAcquireSharedInterruptibly
鏂规硶鏉ヨ嚜 AQS 鐨勫唴閮ㄦ柟娉曪紝涓庢垜浠湪瀛︿範绔炰簤閿佹椂鏈夐儴鍒嗙煡璇嗙偣鐩稿悓锛屼絾涔熸湁涓€浜涘樊寮傘€傛瘮濡傦細addWaiter(Node.SHARED)
锛?tryAcquireShared
锛屾垜浠富瑕佷粙缁嶄笅杩欏唴瀹广€? -
Node.SHARED
锛屽叾瀹炴病鏈夌壒娈婂惈涔夛紝瀹冨彧鏄竴涓爣璁颁綔鐢紝鐢ㄤ簬鍒ゆ柇鏄惁鍏变韩銆?final boolean isShared() { return nextWaiter == SHARED; }
-
tryAcquireShared
锛屼富瑕佹槸鏉ヨ嚜Semaphore
鍏变韩閿佷腑鍏钩閿佸拰闈炲叕骞抽攣鐨勫疄鐜般€傜敤鏉ヨ幏鍙栧悓姝ョ姸鎬併€? -
setHeadAndPropagate(node, r)
锛屽鏋渞 > 0锛屽悓姝ユ垚鍔熷悗鍒欏皢褰撳墠绾跨▼缁撶偣璁剧疆涓哄ご缁撶偣锛屽悓鏃?helpGC锛宲.next = null锛屾柇閾炬搷浣溿€? -
shouldParkAfterFailedAcquire(p, node)
锛岃皟鏁村悓姝ラ槦鍒椾腑 node 缁撶偣鐨勭姸鎬侊紝骞跺垽鏂槸鍚﹀簲璇ヨ鎸傝捣銆傝繖鍦ㄦ垜浠箣鍓嶅叧浜庨攣鐨勬枃绔犱腑宸茬粡浠嬬粛銆? -
parkAndCheckInterrupt()
锛屽垽鏂槸鍚﹂渶瑕佽涓柇锛屽鏋滀腑鏂洿鎺ユ姏鍑哄紓甯革紝褰撳墠缁撶偣璇锋眰涔熷氨缁撴潫銆? -
cancelAcquire(node)
锛屽彇娑堣鑺傜偣鐨勭嚎绋嬭姹傘€?
4. CountDownLatch 鍏变韩閿佷娇鐢?/span>
CountDownLatch 涔熸槸鍏变韩閿佺殑涓€绉嶇被鍨嬶紝涔嬫墍浠ュ湪杩欓噷浣撶幇涓嬶紝鏄洜涓哄畠鍜?Semaphore 鍏变韩閿侊紝鏃㈢浉浼兼湁涓嶅悓銆?/p>
CountDownLatch 鏇村浣撶幇鐨勭粍鍥竴娉㈢殑鎬濇兂锛屽悓鏍锋槸鎺у埗浜烘暟锛屼絾鏄渶瑕佸涓€绐濄€傛瘮濡傦細鎴戜滑璇磋繃鐨?涓汉涓€璧蜂笂鐨垝鑹囥€佷袱涓汉涓€璧蜂笂璺疯贩鏉裤€?span class="mq-394">2涓汉涓€璧疯共鍧戞垜娌¤杩?/span>锛岃繖鏍风殑鏂瑰紡灏辨槸闂ㄩ棭 CountDownLatch 閿佺殑鎬濇兂銆?/p>
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(10);
ExecutorService exec = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
exec.execute(() -> {
try {
int millis = new Random().nextInt(10000);
System.out.println("绛夊緟娓稿涓婅埞锛岃€楁椂锛? + millis + "(millis)");
Thread.sleep(millis);
} catch (Exception ignore) {
} finally {
latch.countDown(); // 瀹屼簨涓€涓墸鍑忎竴涓悕棰?/span>
}
});
}
// 绛夊緟娓稿
latch.await();
System.out.println("鑸归暱鎬ヨ簛浜嗭紝寮€鑸?");
// 鍏抽棴绾跨▼姹?/span>
exec.shutdown();
}
-
杩欎竴涓叕鍥父鑸圭殑鍦烘櫙妗堜緥锛岀瓑寰?0涓箻瀹笂浼狅紝浠栦滑姣旇緝澧ㄨ抗銆? -
涓婁竴涓墸鍑忎竴涓? latch.countDown()
-
绛夊緟娓稿閮戒笂鑸? latch.await()
-
鏈€鍚庤埞闀垮紑鑸癸紒锛? 鎬ヨ簛浜?/code>
銆屾祴璇曠粨鏋溿€?/strong>
绛夊緟娓稿涓婅埞锛岃€楁椂锛?span class="mq-437">6689(millis)
绛夊緟娓稿涓婅埞锛岃€楁椂锛?span class="mq-438">2303(millis)
绛夊緟娓稿涓婅埞锛岃€楁椂锛?span class="mq-439">8208(millis)
绛夊緟娓稿涓婅埞锛岃€楁椂锛?span class="mq-440">435(millis)
绛夊緟娓稿涓婅埞锛岃€楁椂锛?span class="mq-441">9489(millis)
绛夊緟娓稿涓婅埞锛岃€楁椂锛?span class="mq-442">4937(millis)
绛夊緟娓稿涓婅埞锛岃€楁椂锛?span class="mq-443">2771(millis)
绛夊緟娓稿涓婅埞锛岃€楁椂锛?span class="mq-444">4823(millis)
绛夊緟娓稿涓婅埞锛岃€楁椂锛?span class="mq-445">1989(millis)
绛夊緟娓稿涓婅埞锛岃€楁椂锛?span class="mq-446">8506(millis)
鑸归暱鎬ヨ簛浜嗭紝寮€鑸?
Process finished with exit code 0
-
鍦ㄤ綘瀹為檯鐨勬祴璇曚腑浼氬彂鐜帮紝 鑸归暱鎬ヨ簛浜嗭紝寮€鑸?
锛屼細闇€瑕佺瓑寰呬竴娈垫椂闂淬€? -
杩欓噷浣撶幇鐨勫氨鏄棬闂╃殑鎬濇兂锛岀粍闃熴€佷竴娉㈠甫璧般€? -
CountDownLatch 鐨勫疄鐜颁笌 Semaphore 鍩烘湰鐩稿悓銆佺粏鑺傜暐鏈夊樊寮傦紝灏变笉鍐嶅仛婧愮爜鍒嗘瀽浜嗐€?
鍥涖€佹€荤粨
-
鍦ㄦ湁浜?AQS銆丆LH銆丮CS锛岀瓑鐩稿叧閿佺殑鐭ヨ瘑浜嗚В鍚庯紝鍦ㄥ涔犲叾浠栫煡璇嗙偣涔熺浉瀵瑰鏄撱€傚熀鏈互涓婂拰鍓嶅嚑绔犺妭鍏充簬閿佺殑浠嬬粛锛屼篃鏄潰璇曚腑瀹规槗闂埌鐨勭偣銆? 鍙兘鐢变簬鐩墠鍒嗗竷寮忓紑鍙戣緝澶氾紝鍗曟満鐨勫绾跨▼鎬ц兘鍘嬫Θ涓€鑸緝灏戯紝浣嗘槸瀵硅繖閮ㄥ垎鐭ヨ瘑鐨勪簡瑙i潪甯搁噸瑕?/span> -
寰楃泭浜嶭ee鑰佺埛瀛愮殑鎿嶅垁锛屽苟鍙戝寘閿佺殑璁捐鐪熺殑闈炲父浼樼銆傛瘡涓€澶勭殑瀹炵幇閮藉彲浠ヨ鏄簿鐩婃眰绮撅紝鎵€浠ュ湪瀛︿範鐨勬椂鍊欏彲浠ユ妸灏忓倕鍝ョ殑鏂囩珷褰撲綔鎶涚爾锛屼箣鍚庣户缁繁鎸栬璁$簿楂擄紝涓嶆柇娣卞叆銆? -
鍏变韩閿佺殑浣跨敤鍙兘骞虫椂骞朵笉澶氾紝浣嗗鏋滀綘闇€瑕佽璁′竴娆剧被浼兼暟鎹簱绾跨▼姹犵殑璁捐锛岄偅涔堣繖鏍风殑淇″彿閲忛攣鐨勬€濇兂灏遍潪甯搁噸瑕佷簡銆傛墍浠ュ湪瀛︿範鐨勬椂鍊欎篃闇€瑕佹湁鎶€鏈縼绉荤殑鑳斤紝涓嶆柇鎶婅繖浜涚煡璇嗗鐢ㄥ埌瀹為檯鐨勪笟鍔″紑鍙戜腑銆?
浜斻€佺郴鍒楁帹鑽?/span>
bugstack铏礊鏍?/strong>
娌夋穩銆佸垎浜€佹垚闀匡紝璁╄嚜宸卞拰浠栦汉閮借兘鏈夋墍鏀惰幏锛?/span>
浣滆€呭皬鍌呭摜澶氬勾浠庝簨涓€绾夸簰鑱旂綉Java
寮€鍙戯紝浠?9骞村紑濮嬬紪鍐欏伐浣滃拰瀛︿範鍘嗙▼鐨勬妧鏈眹鎬伙紝鏃ㄥ湪涓哄ぇ瀹舵彁渚涗竴涓緝娓呮櫚璇︾粏鐨勬牳蹇冩妧鑳藉涔犳枃妗c€傚鏋滄湰鏂囪兘涓烘偍鎻愪緵甯姪锛岃缁欎簣鏀寔(鍏虫敞銆佺偣璧炪€佸垎浜?锛?img data-ratio="1" src="/img?url=https://mmbiz.qpic.cn/sz_mmbiz_png/zTfAIs5rNXjk2CsH6SOUSmNNRmT72WHVIQdSibib4TDkwIHev4eWfyCYBsZz5xG88W6Qy6a69iaemCoxVezmgtl1Q/640?wx_fmt=png" data-type="png" data-w="20" _width="20px" alt="闈㈢粡鎵嬪唽 路 绗?8绡囥€夾QS 鍏变韩閿侊紝Semaphore銆丆ountDownLatch锛屽惉璇存暟鎹簱杩炴帴姹犲彲浠ョ敤鍒帮紒銆? class="mq-483">
鎰熻阿鏀寔灏忓倕鍝ュ師鍒涳紝娆㈣繋鐐瑰嚮鍦ㄧ湅鍜?/span>杞彂
以上是关于闈㈢粡鎵嬪唽 路 绗?8绡囥€夾QS 鍏变韩閿侊紝Semaphore銆丆ountDownLatch锛屽惉璇存暟鎹簱杩炴帴姹犲彲浠ョ敤鍒帮紒銆?/h1>