摘要:公平策略在多個線程爭用鎖的情況下,公平策略傾向于將訪問權(quán)授予等待時間最長的線程。使用方式的典型調(diào)用方式如下二類原理的源碼非常簡單,它通過內(nèi)部類實現(xiàn)了框架,接口的實現(xiàn)僅僅是對的的簡單封裝,參見原理多線程進階七鎖框架獨占功能剖析
本文首發(fā)于一世流云的專欄:https://segmentfault.com/blog...一、ReentrantLock類簡介
ReentrantLock類,實現(xiàn)了Lock接口,是一種可重入的獨占鎖,它具有與使用 synchronized 相同的一些基本行為和語義,但功能更強大。ReentrantLock內(nèi)部通過內(nèi)部類實現(xiàn)了AQS框架(AbstractQueuedSynchronizer)的API來實現(xiàn)獨占鎖的功能。
1.1 類聲明ReentrantLock類直接實現(xiàn)了Lock接口:
ReentrantLock類提供了兩類構(gòu)造器:
ReentrantLock類的其中一個構(gòu)造器提供了指定公平策略 / 非公平策略的功能,默認為非公平策略。
公平策略:在多個線程爭用鎖的情況下,公平策略傾向于將訪問權(quán)授予等待時間最長的線程。也就是說,相當(dāng)于有一個線程等待隊列,先進入等待隊列的線程后續(xù)會先獲得鎖,這樣按照“先來后到”的原則,對于每一個等待線程都是公平的。
非公平策略:在多個線程爭用鎖的情況下,能夠最終獲得鎖的線程是隨機的(由底層OS調(diào)度)。
注意:一般情況下,使用公平策略的程序在多線程訪問時,總體吞吐量(即速度很慢,常常極其慢)比較低,因為此時在線程調(diào)度上面的開銷比較大。
舉個例子:
假設(shè)采用公平策略,線程A首先獲取了鎖,線程B和線程C等待獲取鎖,如下圖:
當(dāng)線程A釋放鎖時,線程B將經(jīng)歷從 掛起->喚醒 的線程調(diào)度過程,線程調(diào)度非常耗時。
在線程B的 掛起->喚醒 階段:
如果采用非公平策略,那么線程C可以立即獲取鎖,線程C使用完并釋放鎖后,線程B可能才剛喚醒完成;此時線程B又可以去獲取鎖,這樣線程B和線程C的效率都得到提升,系統(tǒng)吞吐量提升;
如果采用公平策略,線程C即使可用,也要等到線程調(diào)度完成,整個系統(tǒng)的吞吐量降低。
因此,當(dāng)線程持有鎖的時間相對較長或者線程請求鎖的平均時間間隔較長時,可以考慮使用公平策略。此時線程調(diào)度產(chǎn)生的耗時間隔影響會較小。
1.3 使用方式ReentrantLock的典型調(diào)用方式如下:
class X { private final ReentrantLock lock = new ReentrantLock(); // ... public void m() { lock.lock(); // block until condition holds try { // ... method body } finally { lock.unlock(); } } }二、ReentrantLock類原理
ReentrantLock的源碼非常簡單,它通過內(nèi)部類實現(xiàn)了AQS框架,Lock接口的實現(xiàn)僅僅是對AQS的api的簡單封裝,
參見AQS原理:Java多線程進階(七)—— juc-locks鎖框架:AQS獨占功能剖析(2)
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/71526.html
摘要:關(guān)于接口的介紹,可以參見多線程進階二鎖框架接口。最終線程釋放了鎖,并進入阻塞狀態(tài)。當(dāng)線程被通知喚醒時,則是將條件隊列中的結(jié)點轉(zhuǎn)換成等待隊列中的結(jié)點,之后的處理就和獨占功能完全一樣。 showImg(https://segmentfault.com/img/remote/1460000016012490); 本文首發(fā)于一世流云的專欄:https://segmentfault.com/bl...
摘要:整個包,按照功能可以大致劃分如下鎖框架原子類框架同步器框架集合框架執(zhí)行器框架本系列將按上述順序分析,分析所基于的源碼為。后,根據(jù)一系列常見的多線程設(shè)計模式,設(shè)計了并發(fā)包,其中包下提供了一系列基礎(chǔ)的鎖工具,用以對等進行補充增強。 showImg(https://segmentfault.com/img/remote/1460000016012623); 本文首發(fā)于一世流云專欄:https...
摘要:開始獲取鎖終于輪到出場了,的調(diào)用過程和完全一樣,同樣拿不到鎖,然后加入到等待隊列隊尾然后,在阻塞前需要把前驅(qū)結(jié)點的狀態(tài)置為,以確保將來可以被喚醒至此,的執(zhí)行也暫告一段落了安心得在等待隊列中睡覺。 showImg(https://segmentfault.com/img/remote/1460000016012467); 本文首發(fā)于一世流云的專欄:https://segmentfault...
摘要:好了,繼續(xù)向下執(zhí)行,嘗試獲取鎖失敗后,會調(diào)用首先通過方法,將包裝成共享結(jié)點,插入等待隊列,插入完成后隊列結(jié)構(gòu)如下然后會進入自旋操作,先嘗試獲取一次鎖,顯然此時是獲取失敗的主線程還未調(diào)用,同步狀態(tài)還是。 showImg(https://segmentfault.com/img/remote/1460000016012541); 本文首發(fā)于一世流云的專欄:https://segmentfa...
摘要:關(guān)于,最后有兩點規(guī)律需要注意當(dāng)?shù)牡却犃嘘犑捉Y(jié)點是共享結(jié)點,說明當(dāng)前寫鎖被占用,當(dāng)寫鎖釋放時,會以傳播的方式喚醒頭結(jié)點之后緊鄰的各個共享結(jié)點。當(dāng)?shù)牡却犃嘘犑捉Y(jié)點是獨占結(jié)點,說明當(dāng)前讀鎖被使用,當(dāng)讀鎖釋放歸零后,會喚醒隊首的獨占結(jié)點。 showImg(https://segmentfault.com/img/remote/1460000016012293); 本文首發(fā)于一世流云的專欄:...
閱讀 2047·2023-04-25 15:45
閱讀 1430·2021-09-29 09:34
閱讀 2576·2021-09-03 10:30
閱讀 2078·2019-08-30 15:56
閱讀 1509·2019-08-29 15:31
閱讀 1331·2019-08-29 15:29
閱讀 3256·2019-08-29 11:24
閱讀 3114·2019-08-26 13:45