您好,登錄后才能下訂單哦!
這篇文章主要講解了“如何理解ReentrantLock非公平鎖源碼”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“如何理解ReentrantLock非公平鎖源碼”吧!
1.鎖
java中,加鎖的方式
synchronized,這個(gè)是 java 底層實(shí)現(xiàn)的,也就是 C 語(yǔ)言實(shí)現(xiàn)的。
. lock,這個(gè)是 java.util.concurrent 包下面的,是 java語(yǔ)言實(shí)現(xiàn)的。
2.ReentrantLock
ReentrantLock 是 Lock 的一種實(shí)現(xiàn),是一種可重入的公平或非公平鎖。默認(rèn)是非公平鎖。
2.1 Lock的創(chuàng)建
首先看下鎖的創(chuàng)建和使用代碼:
//創(chuàng)建鎖 Lock lock = new ReentrantLock(); //加鎖 lock.lock(); //釋放鎖 lock.unlock();
然后看下創(chuàng)建的是 ReentrantLock 的構(gòu)造函數(shù):
public ReentrantLock() { sync = new NonfairSync(); }
NonfairSync 就是非公平鎖。所以 ReentrantLock 默認(rèn)是非公平鎖的實(shí)現(xiàn)
2.2 lock()
加鎖的邏輯就比較復(fù)雜了,因?yàn)榇嬖诰€程競(jìng)爭(zhēng)。所以有兩種情況,一種是競(jìng)爭(zhēng)到鎖的處理,一種是沒(méi)有競(jìng)爭(zhēng)到鎖的處理。
首先我們還是來(lái)看下 lock() 方法,因?yàn)樽罱K是非公平的實(shí)現(xiàn),所以直接看 NonfairSync 里面的 lock 方法。
final void lock() { if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); }
2.3 沒(méi)有獲取到鎖的邏輯 acquire()
直接上代碼:
public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); }
還是3個(gè)方法,阿粉一個(gè)一個(gè)的說(shuō)。
tryAcquire(arg) ,還是先看代碼在分析。
final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) // overflow throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; }
a. 獲取 state ,如果等于0,說(shuō)明之前獲得鎖的線程已經(jīng)釋放了,那么這個(gè)線程就會(huì)再次去競(jìng)爭(zhēng)鎖,這就是非公平鎖的體現(xiàn),如果是公平鎖,是沒(méi)有這個(gè)判斷的。
b. 如果前一個(gè)獲得鎖的線程沒(méi)有釋放鎖,那么就判斷是否是同一個(gè)線程,是的話就會(huì)將 state 加 1。這個(gè)就是重入鎖的體現(xiàn)。
c. 如果都不滿足,那么返回 false。
acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) ,再次獲取鎖沒(méi)有成功,并且又不是可重入鎖,那么就存入一個(gè)阻塞隊(duì)列里面。里面還有一點(diǎn)邏輯,就不展開了,有興趣可以自己看下。
selfInterrupt(); 這個(gè)是當(dāng)前線程的中斷標(biāo)志,作用就是在線程在阻塞的是否,客戶端通過(guò)調(diào)用了中斷線程的方法 interrupt(),那么該線程被喚醒的時(shí)候,就會(huì)有響應(yīng)的處理。具體要看這個(gè)線程 run 方法里面的代碼邏輯。
2.4 unlock()
protected final boolean tryRelease(int releases) { int c = getState() - releases; if (Thread.currentThread() != getExclusiveOwnerThread()) throw new IllegalMonitorStateException(); boolean free = false; if (c == 0) { free = true; setExclusiveOwnerThread(null); } setState(c); return free; }
state - 1,如果大于0,說(shuō)明釋放的是重入鎖,只需要修改 state 就行了
如果等于0,說(shuō)明要釋放鎖,釋放鎖首先需要把獨(dú)占線程設(shè)置為null,再把state設(shè)置為0。
感謝各位的閱讀,以上就是“如何理解ReentrantLock非公平鎖源碼”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)如何理解ReentrantLock非公平鎖源碼這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。