馃敟甯稿湪娌宠竟璧帮紝鍝湁涓嶆箍闉嬨€傛垨璁搁潰璇曡繃绋嬩腑浣犻亣鍒扮殑闂灏卞湪杩欏憿锛?/strong>
馃敟鍏虫敞涓汉绠€浠嬶紝闈㈣瘯涓嶈糠璺?/strong>~
涓€銆丄QS鍘熺悊 锛堝皬绫?浜笢锛?/h2>
杩欓亾棰樻兂鑰冨療浠€涔堬紵
鏄惁浜嗚ВJava骞跺彂缂栫▼鐨勭浉鍏崇煡璇嗭紵
鑰冨療鐨勭煡璇嗙偣
AQS鐨勫師鐞?/p>
鑰冪敓搴旇濡備綍鍥炵瓟
浠€涔堟槸AQS
AQS鍗矨bstractQueuedSynchronizer锛屾槸涓€涓敤浜庢瀯寤洪攣鍜屽悓姝ュ櫒鐨勬鏋躲€傚畠鑳介檷浣庢瀯寤洪攣鍜屽悓姝ュ櫒鐨勫伐浣滈噺锛岃繕鍙互閬垮厤澶勭悊澶氫釜浣嶇疆涓婂彂鐢熺殑绔炰簤闂銆傚湪鍩轰簬AQS鏋勫缓鐨勫悓姝ュ櫒涓紝鍙彲鑳藉湪涓€涓椂鍒诲彂鐢熼樆濉烇紝浠庤€岄檷浣庝笂涓嬫枃鍒囨崲鐨勫紑閿€锛屽苟鎻愰珮鍚炲悙閲忋€?/p>
AQS鏍稿績鎬濇兂鏄紝濡傛灉琚姹傜殑鍏变韩璧勬簮绌洪棽锛岄偅涔堝氨灏嗗綋鍓嶈姹傝祫婧愮殑绾跨▼璁剧疆涓烘湁鏁堢殑宸ヤ綔绾跨▼锛屽皢鍏变韩璧勬簮璁剧疆涓洪攣瀹氱姸鎬侊紱濡傛灉鍏变韩璧勬簮琚崰鐢紝灏遍渶瑕佷竴瀹氱殑闃诲绛夊緟鍞ら啋鏈哄埗鏉ヤ繚璇侀攣鍒嗛厤銆傝繖涓満鍒朵富瑕佺敤鐨勬槸CLH闃熷垪鐨勫彉浣撳疄鐜扮殑锛屽皢鏆傛椂鑾峰彇涓嶅埌閿佺殑绾跨▼鍔犲叆鍒伴槦鍒椾腑銆?/p>
CLH
CLH鎸囩殑鏄細涓変綅鍒涗綔鑰呯殑鍚嶅瓧绠€绉?Craig銆丩andin and Hagersten (CLH)銆傛槸涓€绉嶅熀浜庨摼琛ㄧ殑鍙墿灞曘€侀珮鎬ц兘銆佸叕骞崇殑鑷棆閿侊紝鐢宠绾跨▼浠呬粎鍦ㄦ湰鍦板彉閲忎笂鑷棆锛屽畠涓嶆柇杞鍓嶉┍鐨勭姸鎬侊紝鍋囪鍙戠幇鍓嶉┍閲婃斁浜嗛攣灏辩粨鏉熻嚜鏃嬨€?/p>
AQS涓殑闃熷垪鏄疌LH鍙樹綋鐨勮櫄鎷熷弻鍚戦槦鍒楋紙FIFO锛夛紝AQS鏄€氳繃灏嗘瘡鏉¤姹傚叡浜祫婧愮殑绾跨▼灏佽鎴愪竴涓妭鐐规潵瀹炵幇閿佺殑鍒嗛厤銆?/p>

AQS鏀寔鐙崰閿侊紙exclusive锛夊拰鍏变韩閿?share)涓ょ妯″紡銆?/p>
- 鐙崰閿侊細鍙兘琚竴涓嚎绋嬭幏鍙栧埌(Reentrantlock)銆?/li>
- 鍏变韩閿侊細鍙互琚涓嚎绋嬪悓鏃惰幏鍙?CountDownLatch,ReadWriteLock)銆?/li>
鏃犺鏄嫭鍗犻攣杩樻槸鍏变韩閿侊紝鏈川涓婇兘鏄AQS鍐呴儴鐨勪竴涓彉閲弒tate鐨勮幏鍙栥€俿tate鏄竴涓師瀛愮殑int鍙橀噺锛岀敤鏉ヨ〃绀洪攣鐘舵€併€佽祫婧愭暟绛夈€?/p>

鍚屾闃熷垪鐨勪綔鐢ㄦ槸锛氬綋绾跨▼鑾峰彇璧勬簮澶辫触涔嬪悗锛屽氨杩涘叆鍚屾闃熷垪鐨勫熬閮ㄤ繚鎸佽嚜鏃嬬瓑寰咃紝涓嶆柇鍒ゆ柇鑷繁鏄惁鏄摼琛ㄧ殑澶磋妭鐐癸紝濡傛灉鏄ご鑺傜偣锛屽氨涓嶆柇鍙傝瘯鑾峰彇璧勬簮锛岃幏鍙栨垚鍔熷悗鍒欓€€鍑哄悓姝ラ槦鍒椼€?/p>
鏉′欢闃熷垪鏄负Lock瀹炵幇鐨勪竴涓熀纭€鍚屾鍣紝骞朵笖涓€涓嚎绋嬪彲鑳戒細鏈夊涓潯浠堕槦鍒楋紝鍙湁鍦ㄤ娇鐢ㄤ簡Condition鎵嶄細瀛樺湪鏉′欢闃熷垪銆?/p>
AQS涓寘鍚竴涓唴閮ㄧ被:Node銆傝鍐呴儴绫绘槸涓€涓弻鍚戦摼琛紝淇濆瓨鍓嶅悗鑺傜偣锛岀劧鍚庢瘡涓妭鐐瑰瓨鍌ㄤ簡褰撳墠鐨勭姸鎬亀aitStatus銆佸綋鍓嶇嚎绋媡hread銆傚悓姝ラ槦鍒楀拰鏉′欢闃熷垪閮芥槸鐢变竴涓釜Node缁勬垚鐨勩€?/p>
static final class Node {
static final Node EXCLUSIVE = null;
//褰撳墠鑺傜偣鐢变簬瓒呮椂鎴栦腑鏂鍙栨秷
static final int CANCELLED = 1;
//琛ㄧず褰撳墠鑺傜偣鐨勫墠鑺傜偣琚樆濉?
static final int SIGNAL = -1;
//褰撳墠鑺傜偣鍦ㄧ瓑寰卌ondition
static final int CONDITION = -2;
//鐘舵€侀渶瑕佸悜鍚庝紶鎾?
static final int PROPAGATE = -3;
volatile int waitStatus;
volatile Node prev;
volatile Node next;
volatile Thread thread;
Node nextWaiter;
final boolean isShared() {
return nextWaiter == SHARED;
}
final Node predecessor() throws NullPointerException {
Node p = prev;
if (p == null)
throw new NullPointerException();
else
return p;
}
Node() { // Used to establish initial head or SHARED marker
}
Node(Thread thread, Node mode) { // Used by addWaiter
this.nextWaiter = mode;
this.thread = thread;
}
Node(Thread thread, int waitStatus) { // Used by Condition
this.waitStatus = waitStatus;
this.thread = thread;
}
}
鐙崰妯″紡涓嬭幏鍙栬祫婧?
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
acquire(int arg)棣栧厛璋冪敤tryAcquire(arg)灏濊瘯鐩存帴鑾峰彇璧勬簮锛屽鏋滆幏鍙栨垚鍔燂紝鍥犱负涓庤繍绠楃殑鐭矾鎬ц川锛屽氨涓嶅啀鎵ц鍚庨潰鐨勫垽鏂紝鐩存帴杩斿洖銆倀ryAcquire(int arg)鐨勫叿浣撳疄鐜扮敱瀛愮被璐熻矗銆傚鏋滄病鏈夌洿鎺ヨ幏鍙栧埌璧勬簮锛屽氨灏嗗綋鍓嶇嚎绋嬪姞鍏ョ瓑寰呴槦鍒楃殑灏鹃儴锛屽苟鏍囪涓虹嫭鍗犳ā寮忥紝浣跨嚎绋嬪湪绛夊緟闃熷垪涓嚜鏃嬬瓑寰呰幏鍙栬祫婧愶紝鐩村埌鑾峰彇璧勬簮鎴愬姛鎵嶈繑鍥炪€傚鏋滅嚎绋嬪湪绛夊緟鐨勮繃绋嬩腑琚腑鏂繃锛屽氨杩斿洖true锛屽惁鍒欒繑鍥瀎alse銆?/p>
濡傛灉acquireQueued(addWaiter(Node.EXCLUSIVE), arg)鎵ц杩囩▼涓涓柇杩囷紝閭d箞if璇彞鐨勬潯浠跺氨鍏ㄩ儴鎴愮珛锛屽氨浼氭墽琛宻elfInterrupt();鏂规硶銆傚洜涓哄湪绛夊緟闃熷垪涓嚜鏃嬬姸鎬佺殑绾跨▼鏄笉浼氬搷搴斾腑鏂殑锛屽畠浼氭妸涓柇璁板綍涓嬫潵锛屽鏋滃湪鑷棆鏃跺彂鐢熻繃涓柇锛屽氨杩斿洖true銆傜劧鍚庡氨浼氭墽琛宻elfInterrupt()鏂规硶锛岃€岃繖涓柟娉曞氨鏄畝鍗曠殑涓柇褰撳墠绾跨▼Thread.currentThread().interrupt();鍏朵綔鐢ㄥ氨鏄ˉ涓婂湪鑷棆鏃舵病鏈夊搷搴旂殑涓柇銆?/p>
鍙互鐪嬪嚭鍦ㄦ暣涓柟娉曚腑锛屾渶閲嶈鐨勫氨鏄痑cquireQueued(addWaiter(Node.EXCLUSIVE), arg)銆傛垜浠鍏堢湅Node addWaiter(Node mode)鏂规硶锛岄【鍚嶆€濅箟锛岃繖涓柟娉曠殑浣滅敤灏辨槸娣诲姞涓€涓瓑寰呰€咃紝鏍规嵁涔嬪墠瀵笰QS涓暟鎹粨鏋勭殑鍒嗘瀽锛屽彲浠ョ煡閬擄紝娣诲姞绛夊緟鑰呭氨鏄皢璇ヨ妭鐐瑰姞鍏ョ瓑寰呴槦鍒椼€?/p>
private Node addWaiter(Node mode) {
Node node = new Node(Thread.currentThread(), mode);
// Try the fast path of enq; backup to full enq on failure
Node pred = tail;
//灏濊瘯蹇€熷叆闃?
if (pred != null) { //闃熷垪宸茬粡鍒濆鍖?
node.prev = pred;
if (compareAndSetTail(pred, node)) {
pred.next = node;
return node; //蹇€熷叆闃熸垚鍔熷悗锛屽氨鐩存帴杩斿洖浜?
}
}
//蹇€熷叆闃熷け璐ワ紝涔熷氨鏄闃熷垪閮借繕娌″垵濮嬪寲锛屽氨浣跨敤enq
enq(node);
return node;
}
//鎵ц鍏ラ槦
private Node enq(final Node node) {
for (;;) {
Node t = tail;
if (t == null) { // Must initialize
//濡傛灉闃熷垪涓虹┖锛岀敤涓€涓┖鑺傜偣鍏呭綋闃熷垪澶?
if (compareAndSetHead(new Node()))
tail = head;//灏鹃儴鎸囬拡涔熸寚鍚戦槦鍒楀ご
} else {
//闃熷垪宸茬粡鍒濆鍖栵紝鍏ラ槦
node.prev = t;
if (compareAndSetTail(t, node)) {
t.next = node;
return t;//鎵撴柇寰幆
}
}
}
}
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();//鎷垮埌node鐨勪笂涓€涓妭鐐?
//鍓嶇疆鑺傜偣涓篽ead锛岃鏄庡彲浠ュ皾璇曡幏鍙栬祫婧愩€傛帓闃熸垚鍔熷悗锛屽皾璇曟嬁閿?
if (p == head && tryAcquire(arg)) {
setHead(node);//鑾峰彇鎴愬姛锛屾洿鏂癶ead鑺傜偣
p.next = null; // help GC
failed = false;
return interrupted;
}
//灏濊瘯鎷块攣澶辫触鍚庯紝鏍规嵁鏉′欢杩涜park
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);
}
}
//鑾峰彇璧勬簮澶辫触鍚庯紝妫€娴嬪苟鏇存柊绛夊緟鐘舵€?
private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
int ws = pred.waitStatus;
if (ws == Node.SIGNAL)
/*
* This node has already set status asking a release
* to signal it, so it can safely park.
*/
return true;
if (ws > 0) {
/*
* Predecessor was cancelled. Skip over predecessors and
* indicate retry.
*/
do {
//濡傛灉鍓嶈妭鐐瑰彇娑堜簡锛岄偅灏卞線鍓嶆壘鍒颁竴涓瓑寰呯姸鎬佺殑鎺ュ緟浣狅紝骞舵帓鍦ㄥ畠鐨勫悗闈?
node.prev = pred = pred.prev;
} while (pred.waitStatus > 0);
pred.next = node;
} else {
/*
* waitStatus must be 0 or PROPAGATE. Indicate that we
* need a signal, but don't park yet. Caller will need to
* retry to make sure it cannot acquire before parking.
*/
compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
}
return false;
}
//闃诲褰撳墠绾跨▼锛岃繑鍥炰腑鏂姸鎬?
private final boolean parkAndCheckInterrupt() {
LockSupport.park(this);
return Thread.interrupted();
}
鍏钩閿佺殑瀹炵幇
鍦ㄥ苟鍙戠幆澧冧腑锛屾瘡涓嚎绋嬪湪鑾峰彇閿佹椂浼氬厛鏌ョ湅姝ら攣缁存姢鐨勭瓑寰呴槦鍒楋紝濡傛灉涓虹┖锛屾垨鑰呭綋鍓嶇嚎绋嬫槸绛夊緟闃熷垪鐨勭涓€涓紝灏卞崰鏈夐攣锛屽惁鍒欏氨浼氬姞鍏ュ埌绛夊緟闃熷垪涓紝浠ュ悗浼氭寜鐓IFO鐨勮鍒欎粠闃熷垪涓彇鍒拌嚜宸便€傚叕骞抽攣鐨勪紭鐐规槸绛夊緟閿佺殑绾跨▼涓嶄細楗挎銆傜己鐐规槸鏁翠綋鍚炲悙鏁堢巼鐩稿闈炲叕骞抽攣瑕佷綆锛岀瓑寰呴槦鍒椾腑闄ょ涓€涓嚎绋嬩互澶栫殑鎵€鏈夌嚎绋嬮兘浼氶樆濉烇紝CPU鍞ら啋闃诲绾跨▼鐨勫紑閿€姣旈潪鍏钩閿佸ぇ銆?/p>
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {//鐘舵€佷负0琛ㄧず鍙互鍔犻攣
if (!hasQueuedPredecessors() && //hasQueuedPredecessors琛ㄧず涔嬪墠鐨勭嚎绋嬫槸鍚︽湁鍦ㄦ帓闃熺殑锛岃繖閲屽姞浜嗭紒琛ㄧず娌℃湁鎺掗槦
compareAndSetState(0, acquires)) { //閭d箞灏卞幓灏濊瘯cas state
setExclusiveOwnerThread(current); //濡傛灉cas鎴愬姛璁剧疆鎺掍粬绾跨▼涓哄綋鍓嶇嚎绋嬶紝琛ㄧず鎴愬姛寰楀埌閿?
return true;
}
}
else if (current == getExclusiveOwnerThread()) {//濡傛灉褰撳墠鐨勬帓浠栫嚎绋嬫槸褰撳墠绾跨▼锛岃〃绀烘槸閲嶅叆
int nextc = c + acquires; //閲嶅叆璁℃暟鍣ㄥ鍔?
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);//鍥犱负宸茬粡鑾峰緱閿佷簡锛屾墍浠ヤ笉鐢╟as鍘昏锛岀洿鎺ヨ鍊煎氨琛?
return true;
}
return false;
}
闈炲叕骞抽攣鐨勫疄鐜?/h4>
鐩存帴灏濊瘯鍗犳湁閿侊紝濡傛灉灏濊瘯澶辫触锛屽氨鍐嶉噰鐢ㄧ被浼煎叕骞抽攣閭g鏂瑰紡銆傞潪鍏钩閿佺殑浼樼偣鏄彲浠ュ噺灏戝敜璧风嚎绋嬬殑寮€閿€锛屾暣浣撶殑鍚炲悙鏁堢巼楂橈紝鍥犱负绾跨▼鏈夊嚑鐜囦笉闃诲鐩存帴鑾峰緱閿侊紝CPU涓嶅繀鍞ら啋鎵€鏈夌嚎绋嬨€傜己鐐规槸澶勪簬绛夊緟闃熷垪涓殑绾跨▼鍙兘浼氶タ姝伙紝鎴栬€呯瓑寰堜箙鎵嶄細鑾峰緱閿併€?/p>
final boolean nonfairTryAcquire(int acquires) {
// 鑾峰彇褰撳墠绾跨▼
final Thread current = Thread.currentThread();
// 鑾峰彇褰撳墠state鐨勫€?
int c = getState();
if (c == 0) {
// 鐪嬬湅璁剧疆鍊兼槸鍚﹁兘鎴愬姛
if (compareAndSetState(0, acquires)) {
// 鍒欏皢褰撳墠绾跨▼璁剧疆涓虹嫭鍗犵嚎绋?
setExclusiveOwnerThread(current);
return true;
}
}
// 杩斿洖鐢眘etExclusiveOwnerThread璁剧疆鐨勬渶鍚庝竴涓嚎绋嬶紱濡傛灉浠庝笉璁剧疆锛屽垯杩斿洖null
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
// 璁剧疆state鐨勫€?
setState(nextc);
return true;
}
return false;
}
閲婃斁閿佸疄鐜?/h4>
閲婃斁閿佷唬鐮佸垎鏋愶細灏濊瘯閲婃斁姝ら攣銆傚鏋滃綋鍓嶇嚎绋嬫槸姝ら攣鐨勬寔鏈夎€咃紝鍒欎繚鐣欒鏁板皢鍑忓皯銆?濡傛灉淇濇寔璁℃暟鐜板湪涓洪浂锛屽垯閲婃斁閿佸畾銆?濡傛灉褰撳墠绾跨▼涓嶆槸姝ら攣鐨勬寔鏈夎€咃紝鍒欐姏鍑篒llegalMonitorStateException銆?/p>
public void unlock() {
sync.release(1);
}
sync.release(1) 璋冪敤鐨勬槸AbstractQueuedSynchronizer涓殑release鏂规硶
## AbstractQueuedSynchronizer
public final boolean release(int arg) {
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}
鍒嗘瀽tryRelease(arg)鏂规硶锛宼ryRelease(arg)璇ユ柟娉曡皟鐢ㄧ殑鏄疪eentrantLock涓?/p>
protected final boolean tryRelease(int releases) {
// 鑾峰彇褰撳墠閿佹寔鏈夌殑绾跨▼鏁伴噺鍜岄渶瑕侀噴鏀剧殑鍊艰繘琛岀浉鍑?
int c = getState() - releases;
// 濡傛灉褰撳墠绾跨▼涓嶆槸閿佸崰鏈夌殑绾跨▼鎶涘嚭寮傚父
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
// 濡傛灉姝ゆ椂c = 0灏辨剰鍛崇潃state = 0锛屽綋鍓嶉攣娌℃湁琚换鎰忕嚎绋嬪崰鏈?
// 灏嗗綋鍓嶆墍鐨勫崰鏈夌嚎绋嬭缃负绌?
if (c == 0) {
free = true;
setExclusiveOwnerThread(null);
}
// 璁剧疆state鐨勫€间负 0
setState(c);
return free;
}
濡傛灉澶磋妭鐐逛笉涓虹┖锛屽苟涓攚aitStatus != 0锛屽敜閱掑悗缁妭鐐瑰鏋滃瓨鍦ㄧ殑璇濄€傝繖閲岀殑鍒ゆ柇鏉′欢涓轰粈涔堟槸h != null && h.waitStatus != 0锛熷洜涓篽 == null鐨勮瘽锛孒ead杩樻病鍒濆鍖栥€傚垵濮嬫儏鍐典笅锛宧ead == null锛岀涓€涓妭鐐瑰叆闃燂紝Head浼氳鍒濆鍖栦竴涓櫄鎷熻妭鐐广€傛墍浠ヨ锛岃繖閲屽鏋滆繕娌℃潵寰楀強鍏ラ槦锛屽氨浼氬嚭鐜癶ead == null 鐨勬儏鍐点€?/p>
- h != null && waitStatus == 0 琛ㄦ槑鍚庣户鑺傜偣瀵瑰簲鐨勭嚎绋嬩粛鍦ㄨ繍琛屼腑锛屼笉闇€瑕佸敜閱?/li>
- h != null && waitStatus < 0 琛ㄦ槑鍚庣户鑺傜偣鍙兘琚樆濉炰簡锛岄渶瑕佸敜閱?/li>
private void unparkSuccessor(Node node) {
// 鑾峰彇澶寸粨鐐箇aitStatus
int ws = node.waitStatus;
if (ws < 0)
compareAndSetWaitStatus(node, ws, 0);
// 鑾峰彇褰撳墠鑺傜偣鐨勪笅涓€涓妭鐐?
Node s = node.next;
//濡傛灉涓嬩釜鑺傜偣鏄痭ull鎴栬€呬笅涓妭鐐硅cancelled锛屽氨鎵惧埌闃熷垪鏈€寮€濮嬬殑闈瀋ancelled鐨勮妭鐐?
if (s == null || s.waitStatus > 0) {
s = null;
// 灏变粠灏鹃儴鑺傜偣寮€濮嬫壘寰€鍓嶉亶鍘嗭紝鎵惧埌闃熷垪涓涓€涓獁aitStatus<0鐨勮妭鐐广€?
for (Node t = tail; t != null && t != node; t = t.prev)
if (t.waitStatus <= 0)
s = t;
}
// 濡傛灉褰撳墠鑺傜偣鐨勪笅涓妭鐐逛笉涓虹┖锛岃€屼笖鐘舵€?lt;=0锛屽氨鎶婂綋鍓嶈妭鐐瑰敜閱?
if (s != null)
LockSupport.unpark(s.thread);
}
涓轰粈涔堣浠庡悗寰€鍓嶆壘绗竴涓潪Cancelled鐨勮妭鐐癸紵
private Node addWaiter(Node mode) {
Node node = new Node(Thread.currentThread(), mode);
Node pred = tail;
if (pred != null) {
node.prev = pred;
if (compareAndSetTail(pred, node)) {
pred.next = node;
return node;
}
}
enq(node);
return node;
}
浠庢澶勫彲浠ョ湅鍒帮紝鑺傜偣鍏ラ槦骞朵笉鏄師瀛愭搷浣滐紝涔熷氨鏄锛宯ode.prev = pred, compareAndSetTail(pred, node) 杩欎袱涓湴鏂瑰彲浠ョ湅浣淭ail鍏ラ槦鐨勫師瀛愭搷浣滐紝浣嗘槸姝ゆ椂pred.next = node;杩樻病鎵ц锛屽鏋滆繖涓椂鍊欐墽琛屼簡unparkSuccessor鏂规硶锛屽氨娌″姙娉曚粠鍓嶅線鍚庢壘浜嗭紝鎵€浠ラ渶瑕佷粠鍚庡線鍓嶆壘銆傝繕鏈変竴鐐瑰師鍥狅紝鍦ㄤ骇鐢烠ANCELLED鐘舵€佽妭鐐圭殑鏃跺€欙紝鍏堟柇寮€鐨勬槸Next鎸囬拡锛孭rev鎸囬拡骞舵湭鏂紑锛屽洜姝や篃鏄繀椤昏浠庡悗寰€鍓嶉亶鍘嗘墠鑳藉閬嶅巻瀹屽叏閮ㄧ殑Node銆?鎵€浠ワ紝濡傛灉鏄粠鍓嶅線鍚庢壘锛岀敱浜庢瀬绔儏鍐典笅鍏ラ槦鐨勯潪鍘熷瓙鎿嶄綔鍜孋ANCELLED鑺傜偣浜х敓杩囩▼涓柇寮€Next鎸囬拡鐨勬搷浣滐紝鍙兘浼氬鑷存棤娉曢亶鍘嗘墍鏈夌殑鑺傜偣銆傛墍浠ワ紝鍞ら啋瀵瑰簲鐨勭嚎绋嬪悗锛屽搴旂殑绾跨▼灏变細缁х画寰€涓嬫墽琛屻€?/p>

浜屻€丷eentrantLock鐨勫疄鐜板師鐞?/h2>
杩欓亾棰樻兂鑰冨療浠€涔堬紵
- 鏄惁浜嗚В骞跺彂鐩稿叧鐨勭悊璁虹煡璇?/li>
- 鏄惁瀵逛簬閿佹満鍒舵湁涓叏闈㈢殑鐞嗚璁ょ煡
- 鏄惁瀵逛簬AQS鍘熺悊鏈夎嚜宸辩殑鐞嗚В
鑰冨療鐨勭煡璇嗙偣
- 閿佺殑鍒嗙被锛堝叕骞抽攣銆侀噸鍏ラ攣銆侀噸鍔涘害閿佺瓑绛夛級
- ReentrantLock瀹炵幇鏂瑰紡涓嶴ynchronized瀹炵幇鏂瑰紡鐨勫紓鍚岀偣
鑰冪敓搴旇濡備綍鍥炵瓟
Java涓殑澶ч儴鍒嗗悓姝ョ被锛圠ock銆丼emaphore銆丷eentrantLock绛夛級閮芥槸鍩轰簬闃熷垪鍚屾鍣ㄢ€擜QS瀹炵幇鐨勩€侫QS鍘熺悊瑙?銆?.5 AQS鍘熺悊銆?/strong> 銆?/p>
鍦≧eentrantLock涓湁涓€涓娊璞$被Sync锛?/p>
private final Sync sync;
abstract static class Sync extends AbstractQueuedSynchronizer {
...
}
鍙互鐪嬪埌Sync灏辩户鎵胯嚜AQS锛岃€孯eentrantLock鐨刲ock瑙i攣銆乽nlock閲婃斁閿佺瓑鎿嶄綔鍏跺疄閮芥槸鍊熷姪鐨剆ync鏉ュ畬鎴愩€?/p>
public void lock() {
sync.lock();
}
public void unlock() {
sync.release(1);
}
Sync鏄釜鎶借薄绫伙紝ReentrantLock鏍规嵁浼犲叆鏋勯€犳柟娉曠殑甯冨皵鍨嬪弬鏁板疄渚嬪寲鍑篠ync鐨勫疄鐜扮被FairSync鍜孨onfairSync锛屽垎鍒〃绀哄叕骞抽攣鍜岄潪鍏钩閿併€?/p>
public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair new FairSync() : new NonfairSync();
}
ReentrantLock涓嶢QS鐨勫叧绯诲涓嬶細

NonfairSync
鍦≧eentrantLock鐨勯粯璁ゆ棤鍙傛瀯閫犳柟娉曚腑锛宻ync浼氳鏄疄渚嬪寲涓猴細NonfairSync
琛ㄧず闈炲叕骞抽攣銆?/p>
lock
static final class NonfairSync extends Sync {
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
}
NonfairSync灏辨槸涓€涓狝QS銆傚洜姝ゅ湪鎵цlock鏃讹紝浼氶鍏堝埄鐢–AS锛?銆?.4 CAS鏃犻攣缂栫▼鍘熺悊銆?/strong> 锛夊皾璇曡缃瓵QS鐨剆tate涓?銆傚鏋滆缃垚鍔熻〃绀烘垚鍔熻幏鍙栭攣锛涘惁鍒欒〃绀哄叾浠栫嚎绋嬪凡缁忓崰鐢紝姝ゆ椂浼氫娇鐢?code>AQS#acquire灏嗗皾璇曡幏鍙栭攣澶辫触鐨勭嚎绋嬫斁鍏QS鐨勭瓑寰呴槦鍒楄繘琛岀瓑寰呭苟涓斿皢绾跨▼鎸傝捣銆?/p>
unlock
lock鑾峰彇閿侀渶瑕佸state杩涜鍔?锛岄偅涔堝浜庨噸鍏ラ攣鑰岃█锛岄噸鍏ヤ竴娆″氨闇€瑕佸state鎵ц涓€娆″姞1銆傝繖鏍峰瓙锛屽湪瑙i攣鐨勬椂鍊欙紝姣忔unlock灏卞state鍑忎竴锛岀瓑鍒皊tate鐨勫€间负0鐨勬椂鍊欙紝鎵嶈兘鍞ら啋涓嬩竴涓瓑寰呯嚎绋嬨€?/p>
鍥犳ReentrantLock#unlock
锛屽疄闄呬笂灏辨槸鎵ц浜咥QS鐨剅elease(1)锛?/p>
public void unlock() {
sync.release(1);
}
FairSync
瀵逛簬NonfairSync 鑰岃█锛岀嚎绋嬪彧瑕佹墽琛宭ock璇锋眰锛屽氨浼氶┈涓婂皾璇曡幏鍙栭攣锛屼笉浼氱AQS褰撳墠绠$悊鐨勭瓑寰呴槦鍒椾腑鏄惁瀛樺湪姝e湪绛夊緟鐨勭嚎绋嬶紝杩欏浜庣瓑寰呯殑绾跨▼涓嶅叕骞筹紝鍥犳NonfairSync琛ㄧず闈炲叕骞抽攣銆?/p>
鑰?strong>FairSync琛ㄧず鍏钩閿侊紝浼氬湪lock璇锋眰杩涜鏃讹紝鍏堝垽鏂瑼QS绠$悊鐨勭瓑寰呴槦鍒椾腑鏄惁宸茬粡鏈夋鍦ㄧ瓑寰呯殑绾跨▼锛屾湁鐨勮瘽灏变笉浼氬皾璇曡幏鍙栭攣锛岀洿鎺ヨ繘鍏ョ瓑寰呴槦鍒楋紝淇濊瘉浜嗗叕骞虫€с€傛鏃?code>FairSync#lock瀹為檯涓婃墽琛岀殑灏辨槸AQS鐨刟cquire
static final class FairSync extends Sync {
final void lock() {
acquire(1);
}
}
涓夈€丼ynchronized鐨勫師鐞嗕互鍙婁笌ReentrantLock鐨勫尯鍒€傦紙360锛?/h2>
杩欓亾棰樻兂鑰冨療浠€涔堬紵
- 鏄惁浜嗚В骞跺彂鐩稿叧鐨勭悊璁虹煡璇?/li>
- 鏄惁瀵逛簬閿佹満鍒舵湁涓叏闈㈢殑鐞嗚璁ょ煡
- 鏄惁瀵逛簬AQS鍘熺悊鏈夎嚜宸辩殑鐞嗚В
鑰冨療鐨勭煡璇嗙偣
- 閿佺殑鍒嗙被锛堝叕骞抽攣銆侀噸鍏ラ攣銆侀噸鍔涘害閿佺瓑绛夛級
- ReentrantLock瀹炵幇鏂瑰紡涓嶴ynchronized瀹炵幇鏂瑰紡鐨勫紓鍚岀偣
鑰冪敓搴旇濡備綍鍥炵瓟
Synchronized鐨勫師鐞嗚 銆?.8 Synchronized鍦↗DK1.6涔嬪悗鍋氫簡鍝簺浼樺寲銆?/strong> 銆?/p>
ReentrantLock涓嶴ynchronized鐨勫尯鍒紝闄や簡涓€涓槸Java绫诲疄鐜帮紝涓€涓槸鍏抽敭瀛椾箣澶栵紝杩樺寘鎷細

闄ゆ涔嬪锛孯eenTrantLock鐩稿浜嶴ynchronized杩樻嫢鏈夎嚜宸辩殑鐙湁鐗规€э細
- ReenTrantLock鍙互鎸囧畾鏄叕骞抽攣杩樻槸闈炲叕骞抽攣銆傝€宻ynchronized鍙兘鏄潪鍏钩閿併€傛墍璋撶殑鍏钩閿佸氨鏄厛绛夊緟鐨勭嚎绋嬪厛鑾峰緱閿併€?/li>
- ReenTrantLock鎻愪緵浜嗕竴涓狢ondition锛堟潯浠讹級绫伙紝鐢ㄦ潵瀹炵幇鍒嗙粍鍞ら啋闇€瑕佸敜閱掔殑绾跨▼浠紝鑰屼笉鏄儚synchronized瑕佷箞闅忔満鍞ら啋涓€涓嚎绋嬭涔堝敜閱掑叏閮ㄧ嚎绋嬨€?/li>
- ReenTrantLock鎻愪緵浜嗕竴绉嶈兘澶熶腑鏂瓑寰呴攣鐨勭嚎绋嬬殑鏈哄埗锛岄€氳繃lock.lockInterruptibly()鏉ュ疄鐜拌繖涓満鍒躲€?/li>
4.8 volatile鍏抽敭瀛楀共浜嗕粈涔堬紵锛堜粈涔堝彨鎸囦护閲嶆帓锛?锛堝瓧鑺傝烦鍔級
杩欓亾棰樻兂鑰冨療浠€涔堬紵
鏄惁浜嗚Вvolatile鍏抽敭瀛椾笌鐪熷疄鍦烘櫙浣跨敤
鑰冨療鐨勭煡璇嗙偣
volatile鍏抽敭瀛楃殑姒傚康鍦ㄩ」鐩腑浣跨敤涓庡熀鏈煡璇?/p>
鑰冪敓搴旇濡備綍鍥炵瓟
volatile鏄痡ava鎻愪緵鐨勫彲浠ュ0鏄庡湪鎴愬憳灞炴€у墠鐨勪竴涓叧閿瓧銆傚湪澹版槑涓寘鍚鍏抽敭瀛楃殑浣滅敤鏈夛細
淇濊瘉鍐呭瓨鍙鎬?/h4>
鍙鎬ф槸鎸囩嚎绋嬩箣闂寸殑鍙鎬э紝涓€涓嚎绋嬩慨鏀圭殑鐘舵€佸鍙︿竴涓嚎绋嬫槸鍙鐨勩€備篃灏辨槸涓€涓嚎绋嬩慨鏀圭殑缁撴灉锛屽彟涓€涓嚎绋嬮┈涓婂氨鑳界湅鍒般€?/p>
褰撳闈瀡olatile鍙橀噺杩涜璇诲啓鐨勬椂鍊欙紝姣忎釜绾跨▼鍏堜粠涓诲唴瀛樻嫹璐濆彉閲忓埌CPU缂撳瓨涓紝濡傛灉璁$畻鏈烘湁澶氫釜CPU锛屾瘡涓嚎绋嬪彲鑳藉湪涓嶅悓鐨凜PU涓婅澶勭悊锛岃繖鎰忓懗鐫€姣忎釜绾跨▼鍙互鎷疯礉鍒颁笉鍚岀殑CPU cache涓€?/p>
volatile鍙橀噺涓嶄細琚紦瀛樺湪瀵勫瓨鍣ㄦ垨鑰呭鍏朵粬澶勭悊鍣ㄤ笉鍙鐨勫湴鏂癸紝淇濊瘉浜嗘瘡娆¤鍐欏彉閲忛兘浠庝富鍐呭瓨涓锛岃烦杩嘋PU cache杩欎竴姝ャ€傚綋涓€涓嚎绋嬩慨鏀逛簡杩欎釜鍙橀噺鐨勫€硷紝鏂板€煎浜庡叾浠栫嚎绋嬫槸绔嬪嵆寰楃煡鐨勩€?/p>
绂佹鎸囦护閲嶆帓
鎸囦护閲嶆帓搴忔槸JVM涓轰簡浼樺寲鎸囦护銆佹彁楂樼▼搴忚繍琛屾晥鐜囷紝鍦ㄤ笉褰卞搷鍗曠嚎绋嬬▼搴忔墽琛岀粨鏋滅殑鍓嶆彁涓嬶紝灏藉彲鑳藉湴鎻愰珮骞惰搴︺€傛寚浠ら噸鎺掑簭鍖呮嫭缂栬瘧鍣ㄩ噸鎺掑簭鍜岃繍琛屾椂閲嶆帓搴忋€?/p>
latile鍙橀噺绂佹鎸囦护閲嶆帓搴忋€傞拡瀵箆olatile淇グ鐨勫彉閲忥紝鍦ㄨ鍐欐搷浣滄寚浠ゅ墠鍚庝細鎻掑叆鍐呭瓨灞忛殰锛屾寚浠ら噸鎺掑簭鏃朵笉鑳芥妸鍚庨潰鐨勬寚浠ら噸鎺掑簭鍒板唴瀛樺睆
绀轰緥璇存槑锛?/p>
绀轰緥璇存槑锛?
double r = 2.1; //(1)
double pi = 3.14;//(2)
double area = pi*r*r;//(3)
铏界劧浠g爜璇彞鐨勫畾涔夐『搴忎负1->2->3锛屼絾鏄绠楅『搴?->2->3涓?->1->3瀵圭粨鏋滃苟鏃犲奖鍝嶏紝鎵€浠ョ紪璇戞椂鍜岃繍琛屾椂鍙互鏍规嵁闇€瑕佸1銆?璇彞杩涜閲嶆帓搴忋€?/p>
鎸囦护閲嶆帓甯︽潵鐨勯棶棰?/h5>
濡傛灉涓€涓搷浣滀笉鏄師瀛愮殑锛屽氨浼氱粰JVM鐣欎笅閲嶆帓鐨勬満浼氥€?/p>
绾跨▼A涓?
{
context = loadContext();
inited = true;
}
绾跨▼B涓?
{
if (inited)
fun(context);
}
濡傛灉绾跨▼A涓殑鎸囦护鍙戠敓浜嗛噸鎺掑簭锛岄偅涔圔涓緢鍙兘灏变細鎷垮埌涓€涓皻鏈垵濮嬪寲鎴栧皻鏈垵濮嬪寲瀹屾垚鐨刢ontext,浠庤€屽紩鍙戠▼搴忛敊璇€?/p>
绂佹鎸囦护閲嶆帓鐨勫師鐞?/h5>
volatile鍏抽敭瀛楁彁渚涘唴瀛樺睆闅滅殑鏂瑰紡鏉ラ槻姝㈡寚浠よ閲嶆帓锛岀紪璇戝櫒鍦ㄧ敓鎴愬瓧鑺傜爜鏂囦欢鏃讹紝浼氬湪鎸囦护搴忓垪涓彃鍏ュ唴瀛樺睆闅滄潵绂佹鐗瑰畾绫诲瀷鐨勫鐞嗗櫒閲嶆帓搴忋€?/p>
JVM鍐呭瓨灞忛殰鎻掑叆绛栫暐锛?/p>
鍦ㄦ瘡涓獀olatile鍐欐搷浣滅殑鍓嶉潰鎻掑叆涓€涓猄toreStore灞忛殰锛?/p>
鍦ㄦ瘡涓獀olatile鍐欐搷浣滅殑鍚庨潰鎻掑叆涓€涓猄toreLoad灞忛殰锛?/p>
鍦ㄦ瘡涓獀olatile璇绘搷浣滅殑鍚庨潰鎻掑叆涓€涓狶oadLoad灞忛殰锛?/p>
鍦ㄦ瘡涓獀olatile璇绘搷浣滅殑鍚庨潰鎻掑叆涓€涓狶oadStore灞忛殰銆?/p>
鎸囦护閲嶆帓鍦ㄥ弻閲嶉攣瀹氬崟渚嬫ā寮忎腑鐨勫奖鍝?/strong> 鍩轰簬鍙岄噸妫€楠岀殑鍗曚緥妯″紡(鎳掓眽鍨?
public class Singleton3 {
private static Singleton3 instance = null;
private Singleton3() {}
public static Singleton3 getInstance() {
if (instance == null) {
synchronized(Singleton3.class) {
if (instance == null)
instance = new Singleton3();// 闈炲師瀛愭搷浣?
}
}
return instance;
}
}
instance= new Singleton()骞朵笉鏄竴涓師瀛愭搷浣滐紝鍏跺疄闄呬笂鍙互鎶借薄涓轰笅闈㈠嚑鏉VM鎸囦护锛?/p>
memory =allocate(); //1锛氬垎閰嶅璞$殑鍐呭瓨绌洪棿
ctorInstance(memory); //2锛氬垵濮嬪寲瀵硅薄
instance =memory; //3锛氳缃甶nstance鎸囧悜鍒氬垎閰嶇殑鍐呭瓨鍦板潃
涓婇潰鎿嶄綔2渚濊禆浜庢搷浣?锛屼絾鏄搷浣?骞朵笉渚濊禆浜庢搷浣?銆傛墍浠VM鏄彲浠ラ拡瀵瑰畠浠繘琛屾寚浠ょ殑浼樺寲閲嶆帓搴忕殑锛岀粡杩囬噸鎺掑簭鍚庡涓嬶細
memory =allocate(); //1锛氬垎閰嶅璞$殑鍐呭瓨绌洪棿
instance =memory; //3锛歩nstance鎸囧悜鍒氬垎閰嶇殑鍐呭瓨鍦板潃锛屾鏃跺璞¤繕鏈垵濮嬪寲
ctorInstance(memory); //2锛氬垵濮嬪寲瀵硅薄
鎸囦护閲嶆帓涔嬪悗锛宨nstance鎸囧悜鍒嗛厤濂界殑鍐呭瓨鏀惧湪浜嗗墠闈紝鑰岃繖娈靛唴瀛樼殑鍒濆鍖栬鎺掑湪浜嗗悗闈€傚湪绾跨▼A鎵ц杩欐璧嬪€艰鍙ワ紝鍦ㄥ垵濮嬪寲鍒嗛厤瀵硅薄涔嬪墠灏卞凡缁忓皢鍏惰祴鍊肩粰instance寮曠敤锛屾伆濂藉彟涓€涓嚎绋嬭繘鍏ユ柟娉曞垽鏂璱nstance寮曠敤涓嶄负null锛岀劧鍚庡氨灏嗗叾杩斿洖浣跨敤锛屽鑷村嚭閿欍€?/p>
volatile瑙e喅閲嶆帓
鐢╲olatile鍏抽敭瀛椾慨楗癷nstance鍙橀噺锛屼娇寰梚nstance鍦ㄨ銆佸啓鎿嶄綔鍓嶅悗閮戒細鎻掑叆鍐呭瓨灞忛殰锛岄伩鍏嶉噸鎺掑簭銆?/p>
public class Singleton3 {
private static volatile Singleton3 instance = null;
private Singleton3() {}
public static Singleton3 getInstance() {
if (instance == null) {
synchronized(Singleton3.class) {
if (instance == null)
instance = new Singleton3();
}
}
return instance;
}
}