日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Java多线程系列--“JUC锁”05之 非公平锁

發(fā)布時(shí)間:2023/12/10 java 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java多线程系列--“JUC锁”05之 非公平锁 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

轉(zhuǎn)載自:http://www.cnblogs.com/skywang12345/p/3496651.html點(diǎn)擊打開鏈接

概要

前面兩章分析了"公平鎖的獲取和釋放機(jī)制",這一章開始對“非公平鎖”的獲取鎖/釋放鎖的過程進(jìn)行分析。內(nèi)容包括:
參考代碼
獲取非公平鎖(基于JDK1.7.0_40)
釋放非公平鎖(基于JDK1.7.0_40)
關(guān)于鎖的數(shù)據(jù)結(jié)構(gòu)請參考"Java多線程系列--“JUC鎖”03之 公平鎖(一)?",鎖的使用示例請參考“Java多線程系列--“JUC鎖”02之 互斥鎖ReentrantLock”。

轉(zhuǎn)載請注明出處:http://www.cnblogs.com/skywang12345/p/3496651.html

?

參考代碼

下面給出Java1.7.0_40版本中,ReentrantLock和AQS的源碼,僅供參考!

ReentranLock.java

?View Code

?

AQS(AbstractQueuedSynchronizer.java)

?View Code

?

獲取非公平鎖(基于JDK1.7.0_40)

非公平鎖和公平鎖在獲取鎖的方法上,流程是一樣的;它們的區(qū)別主要表現(xiàn)在“嘗試獲取鎖的機(jī)制不同”。簡單點(diǎn)說,“公平鎖”在每次嘗試獲取鎖時(shí),都是采用公平策略(根據(jù)等待隊(duì)列依次排序等待);而“非公平鎖”在每次嘗試獲取鎖時(shí),都是采用的非公平策略(無視等待隊(duì)列,直接嘗試獲取鎖,如果鎖是空閑的,即可獲取狀態(tài),則獲取鎖)。
在前面的“Java多線程系列--“JUC鎖”03之 公平鎖(一)”中,已經(jīng)詳細(xì)介紹了獲取公平鎖的流程和機(jī)制;下面,通過代碼分析以下獲取非公平鎖的流程。

?

1. lock()

lock()在ReentrantLock.java的NonfairSync類中實(shí)現(xiàn),它的源碼如下:

final void lock() {if (compareAndSetState(0, 1))setExclusiveOwnerThread(Thread.currentThread());elseacquire(1); }

說明
lock()會(huì)先通過compareAndSet(0, 1)來判斷“鎖”是不是空閑狀態(tài)。是的話,“當(dāng)前線程”直接獲取“鎖”;否則的話,調(diào)用acquire(1)獲取鎖。
(01) compareAndSetState()是CAS函數(shù),它的作用是比較并設(shè)置當(dāng)前鎖的狀態(tài)。若鎖的狀態(tài)值為0,則設(shè)置鎖的狀態(tài)值為1。
(02) setExclusiveOwnerThread(Thread.currentThread())的作用是,設(shè)置“當(dāng)前線程”為“鎖”的持有者。

“公平鎖”和“非公平鎖”關(guān)于lock()的對比

公平鎖 -- 公平鎖的lock()函數(shù),會(huì)直接調(diào)用acquire(1)。 非公平鎖 -- 非公平鎖會(huì)先判斷當(dāng)前鎖的狀態(tài)是不是空閑,是的話,就不排隊(duì),而是直接獲取鎖。

?

2. acquire()

acquire()在AQS中實(shí)現(xiàn)的,它的源碼如下:

public final void acquire(int arg) {if (!tryAcquire(arg) &&acquireQueued(addWaiter(Node.EXCLUSIVE), arg))selfInterrupt(); }

(01) “當(dāng)前線程”首先通過tryAcquire()嘗試獲取鎖。獲取成功的話,直接返回;嘗試失敗的話,進(jìn)入到等待隊(duì)列依次排序,然后獲取鎖。
(02) “當(dāng)前線程”嘗試失敗的情況下,會(huì)先通過addWaiter(Node.EXCLUSIVE)來將“當(dāng)前線程”加入到"CLH隊(duì)列(非阻塞的FIFO隊(duì)列)"末尾。
(03) 然后,調(diào)用acquireQueued()獲取鎖。在acquireQueued()中,當(dāng)前線程會(huì)等待它在“CLH隊(duì)列”中前面的所有線程執(zhí)行并釋放鎖之后,才能獲取鎖并返回。如果“當(dāng)前線程”在休眠等待過程中被中斷過,則調(diào)用selfInterrupt()來自己產(chǎn)生一個(gè)中斷。

“公平鎖”和“非公平鎖”關(guān)于acquire()的對比

公平鎖和非公平鎖,只有tryAcquire()函數(shù)的實(shí)現(xiàn)不同;即它們嘗試獲取鎖的機(jī)制不同。這就是我們所說的“它們獲取鎖策略的不同所在之處”!
在“Java多線程系列--“JUC鎖”03之 公平鎖(一)”中,已經(jīng)詳細(xì)介紹了acquire()涉及到的各個(gè)函數(shù)。這里僅對它們有差異的函數(shù)tryAcquire()進(jìn)行說明。

?

非公平鎖的tryAcquire()在ReentrantLock.java的NonfairSync類中實(shí)現(xiàn),源碼如下:

protected final boolean tryAcquire(int acquires) {return nonfairTryAcquire(acquires); }

?

nonfairTryAcquire()在ReentrantLock.java的Sync類中實(shí)現(xiàn),源碼如下:

final boolean nonfairTryAcquire(int acquires) {// 獲取“當(dāng)前線程”final Thread current = Thread.currentThread();// 獲取“鎖”的狀態(tài)int c = getState();// c=0意味著“鎖沒有被任何線程鎖擁有”if (c == 0) {// 若“鎖沒有被任何線程鎖擁有”,則通過CAS函數(shù)設(shè)置“鎖”的狀態(tài)為acquires。// 同時(shí),設(shè)置“當(dāng)前線程”為鎖的持有者。if (compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}}else if (current == getExclusiveOwnerThread()) {// 如果“鎖”的持有者已經(jīng)是“當(dāng)前線程”,// 則將更新鎖的狀態(tài)。int nextc = c + acquires;if (nextc < 0) // overflowthrow new Error("Maximum lock count exceeded");setState(nextc);return true;}return false; }

說明
根據(jù)代碼,我們可以分析出,tryAcquire()的作用就是嘗試去獲取鎖。
(01) 如果“鎖”沒有被任何線程擁有,則通過CAS函數(shù)設(shè)置“鎖”的狀態(tài)為acquires,同時(shí),設(shè)置“當(dāng)前線程”為鎖的持有者,然后返回true。
(02) 如果“鎖”的持有者已經(jīng)是當(dāng)前線程,則將更新鎖的狀態(tài)即可。
(03) 如果不術(shù)語上面的兩種情況,則認(rèn)為嘗試失敗。

“公平鎖”和“非公平鎖”關(guān)于tryAcquire()的對比

公平鎖和非公平鎖,它們嘗試獲取鎖的方式不同。 公平鎖在嘗試獲取鎖時(shí),即使“鎖”沒有被任何線程鎖持有,它也會(huì)判斷自己是不是CLH等待隊(duì)列的表頭;是的話,才獲取鎖。 而非公平鎖在嘗試獲取鎖時(shí),如果“鎖”沒有被任何線程持有,則不管它在CLH隊(duì)列的何處,它都直接獲取鎖。

?

釋放非公平鎖(基于JDK1.7.0_40)

非公平鎖和公平鎖在釋放鎖的方法和策略上是一樣的。
而在前面的“Java多線程系列--“JUC鎖”04之 公平鎖(二)?”中,已經(jīng)對“釋放公平鎖”進(jìn)行了介紹;這里就不再重復(fù)的進(jìn)行說明。

?

總結(jié)
公平鎖和非公平鎖的區(qū)別,是在獲取鎖的機(jī)制上的區(qū)別。表現(xiàn)在,在嘗試獲取鎖時(shí) —— 公平鎖,只有在當(dāng)前線程是CLH等待隊(duì)列的表頭時(shí),才獲取鎖;而非公平鎖,只要當(dāng)前鎖處于空閑狀態(tài),則直接獲取鎖,而不管CLH等待隊(duì)列中的順序。
只有當(dāng)非公平鎖嘗試獲取鎖失敗的時(shí)候,它才會(huì)像公平鎖一樣,進(jìn)入CLH等待隊(duì)列排序等待。

?

總結(jié)

以上是生活随笔為你收集整理的Java多线程系列--“JUC锁”05之 非公平锁的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。