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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

Java8 ReentrantLock 源码分析

發(fā)布時(shí)間:2024/9/30 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java8 ReentrantLock 源码分析 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、ReentrantLock 概述

1.1 ReentrantLock 簡介

故名思義,ReentrantLock 意為可重入鎖,那么什么是可重入鎖呢?可重入意為一個(gè)持有鎖的線程可以對(duì)資源重復(fù)加鎖而不會(huì)阻塞。比如下面這樣:

public synchronized void f1() {f2();}private synchronized void f2() { }

ReentrantLock 除了支持可重入以外,還支持定義公平與非公平策略,默認(rèn)情況下采用非公平策略。公平是指等待時(shí)間最長的線程會(huì)優(yōu)先獲取鎖,也就是獲取鎖是順序的,可以理解為先到先得。

公平鎖保證了鎖的獲取按照 FIFO(先進(jìn)先出)原則,但是需要大量的線程切換。非公平鎖雖然減少了線程之間的切換增大了其吞吐量,但是可能會(huì)造成線程“饑餓”。

1.2 使用方式

public void f1() {ReentrantLock lock = new ReentrantLock();try {lock.lock();// ...} finally {lock.unlock();}}

與 synchronized 不同,使用 ReentrantLock 必須顯示的加鎖與釋放鎖。

1.3 與 synchronized 對(duì)比

相同點(diǎn):

  • 可重入,同一線程可以多次獲得同一個(gè)鎖
  • 都保證了可見性和互斥性

不同點(diǎn):

  • ReentrantLock 可響應(yīng)中斷、可輪回,為處理鎖的不可用性提供了更高的靈活性,synchronized 不可以響應(yīng)中斷
  • ReentrantLock 是 API 級(jí)別的,synchronized 是 JVM 級(jí)別(JVM 內(nèi)置屬性)的,因此內(nèi)置鎖可以與特定的棧幀關(guān)聯(lián)起來
  • ReentrantLock 可以實(shí)現(xiàn)公平鎖,切可以實(shí)現(xiàn)帶有時(shí)間限制的操作
  • ReentrantLock 通過 Condition 可以綁定多個(gè)條件

二、源碼分析

了解了 ReentrantLock 的基本概念后,接下來就一起來看源碼吧。其實(shí) ReentrantLock 內(nèi)的源碼并不多,原因在于很多源碼都在 AbstractQueuedSynchronizer 中,因此想要了解 ReentrantLock 源碼的小伙伴需要先行了解下 AQS。

后面會(huì)給大家推薦幾篇關(guān)于 AQS 源碼介紹的文章,有興趣的可以自行了解,或者到我的 GitHub 去查下相應(yīng)的源碼記錄。點(diǎn)我前往 GitHub

2.1 構(gòu)造函數(shù)

默認(rèn)構(gòu)造函數(shù)

public ReentrantLock() {sync = new NonfairSync();}

有參構(gòu)造函數(shù)

public ReentrantLock(boolean fair) {sync = fair ? new FairSync() : new NonfairSync();}

上面我們說了 ReentrantLock 支持兩種同步策略,分別是公平與非公平,從這個(gè)構(gòu)造函數(shù)中就能體現(xiàn)出來,相信大家看了這個(gè)構(gòu)造函數(shù)也應(yīng)該想到這兩個(gè) FairSync,NonfairSync 對(duì)象應(yīng)該發(fā)揮著至關(guān)重要的作用。下面就來分別分析下對(duì)應(yīng)的源碼。

2.2 NonfairSync

static final class NonfairSync extends Sync {private static final long serialVersionUID = 7316153563782823691L;// 加鎖final void lock() {// 無鎖重入,通過 CAS 第一次嘗試修改同步狀態(tài)值if (compareAndSetState(0, 1))// 設(shè)置當(dāng)前線程獨(dú)占setExclusiveOwnerThread(Thread.currentThread());else// 鎖重入,同步狀態(tài)值 + 1acquire(1);}// 嘗試獲取鎖,直接調(diào)用 Sync 中的 nonfairTryAcquire 方法即可protected final boolean tryAcquire(int acquires) {return nonfairTryAcquire(acquires);}}

acquire 方法是 AQS 中的一個(gè)模板方法,這里我們就不多介紹了,還是要提醒下,大家應(yīng)該先了解 AQS,再來看這篇文章。

tryAcquire 調(diào)用的是 nonfairTryAcquire 方法嘗試去獲取同步狀態(tài),接下來我們看 Sync 類中具體做了哪些實(shí)現(xiàn)。

2.3 Sync

abstract static class Sync extends AbstractQueuedSynchronizer {abstract void lock();// 獨(dú)占模式下嘗試獲取鎖final boolean nonfairTryAcquire(int acquires) {final Thread current = Thread.currentThread();// 獲取同步狀態(tài)int c = getState();// 0 表示無狀態(tài),獨(dú)占鎖模式下可理解為沒有鎖重入if (c == 0) {// 更新同步狀態(tài)值if (compareAndSetState(0, acquires)) {// 獨(dú)占式設(shè)置當(dāng)前線程setExclusiveOwnerThread(current);return true;}}// 設(shè)置獨(dú)占鎖可重入else if (current == getExclusiveOwnerThread()) {int nextc = c + acquires;if (nextc < 0) // overflowthrow new Error("Maximum lock count exceeded");// 重新設(shè)置修改后同步的狀態(tài)值setState(nextc);return true;}// 獲取失敗return false;}// 獨(dú)占模式下嘗試釋放鎖protected final boolean tryRelease(int releases) {// 減小同步狀態(tài)int c = getState() - releases;// 不是當(dāng)前線程拋出異常if (Thread.currentThread() != getExclusiveOwnerThread())throw new IllegalMonitorStateException();boolean free = false;// 如果同步狀態(tài)只為 0,表示可以釋放資源,后面的線程可以嘗試去獲取鎖if (c == 0) {free = true;setExclusiveOwnerThread(null);}// 更新減小后的同步狀態(tài)值setState(c);return free;}}

上面并沒有把 Sync 中的所有源碼貼出來,這些源碼已經(jīng)足夠我們說明問題了。

首先來看 nonfairTryAcquire 方法,該方法用于非公平模式下獲取同步狀態(tài),我們知道 ReentrantLock 是支持可重入的鎖,因此要考慮兩種情況,沒有鎖重入與有鎖重入。其實(shí)源碼也很簡單,有鎖重入的情況下只要增加同步狀態(tài)值即可,這里的同步狀態(tài)值可以理解為鎖重入的次數(shù)。等釋放鎖時(shí)將同步狀態(tài)值再逐次減小,當(dāng)減小為 0 時(shí)表示鎖已經(jīng)釋放,這也是 tryRelease 方法中做的事情。

ReentrantLock 獲取鎖的方式是獨(dú)占的,因此釋放鎖的過程,公平與非公平模式下是相同的。因?yàn)榭紤]到重入的情況,只有當(dāng)同步狀態(tài)減小到為 0 時(shí),才返回 true 表示釋放鎖成功。

2.4 FairSync

static final class FairSync extends Sync {final void lock() {acquire(1);}// 嘗試獲取鎖protected final boolean tryAcquire(int acquires) {// 獲取當(dāng)前線程final Thread current = Thread.currentThread();// 獲取同步狀態(tài)值int c = getState();// 在同步狀態(tài)為 0 的情況下并不是所有線程都可以去獲取同步狀態(tài),等待時(shí)間長的線程會(huì)優(yōu)先獲取同步狀態(tài)if (c == 0) {// 如果隊(duì)列中沒有等待時(shí)間比當(dāng)前線程時(shí)間長的線程,更新同步狀態(tài)值if (!hasQueuedPredecessors() &&compareAndSetState(0, acquires)) {// 設(shè)置當(dāng)前線程獨(dú)占該鎖setExclusiveOwnerThread(current);return true;}}// 保證鎖可重入else if (current == getExclusiveOwnerThread()) {int nextc = c + acquires;if (nextc < 0)throw new Error("Maximum lock count exceeded");// 更新同步狀態(tài)值setState(nextc);return true;}return false;}}

公平策略下獲取同步狀態(tài)的過程與非同步狀態(tài)是類似的,只不過是多了一個(gè) hasQueuedPredecessors 過程判斷,這個(gè)方法用于判斷當(dāng)前線程對(duì)應(yīng)的節(jié)點(diǎn)是否還有前驅(qū)節(jié)點(diǎn),如果有則獲取失敗。下面是具體代碼實(shí)現(xiàn):

public final boolean hasQueuedPredecessors() {Node t = tail; // Read fields in reverse initialization orderNode h = head;Node s;// s 表示頭節(jié)點(diǎn)的后繼節(jié)點(diǎn),如果頭節(jié)點(diǎn)的后繼節(jié)點(diǎn)不是當(dāng)前線程的節(jié)點(diǎn),// 表示當(dāng)前線程并非較先加入隊(duì)列的線程,因此不能成功獲取同步狀態(tài)return h != t &&((s = h.next) == null || s.thread != Thread.currentThread());}

非公平策略下釋放同步狀態(tài)與公平策略下相同,上面已經(jīng)概述過了。

jdk1.8 源碼閱讀:https://github.com/zchen96/jdk1.8-source-code-read

參考資料

《JAVA 并發(fā)編程的藝術(shù)》
深入理解AbstractQueuedSynchronizer(一)
Java并發(fā)之AQS詳解

總結(jié)

以上是生活随笔為你收集整理的Java8 ReentrantLock 源码分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 日本一区二区三区网站 | 亚洲一区精品在线观看 | www.日本精品 | 成人午夜电影网站 | 精品999久久久一级毛片 | 东京热av一区 | 久久精品国产清自在天天线 | 99国产精品免费视频 | 麻豆做爰免费观看 | 成人免费网视频 | 国产aⅴ精品一区二区果冻 台湾性生生活1 | 伊人情人综合 | 老熟女毛茸茸 | 少妇精品偷拍高潮白浆 | 午夜精产品一区二区在线观看的 | 中文字幕精品三级久久久 | 亚洲欧美视频一区二区 | 亚洲午夜精品久久久久久浪潮 | 丁香婷婷一区二区三区 | 姐姐的秘密韩剧免费观看全集中文 | 一区二区三区在线视频免费观看 | 亚洲人精品午夜射精日韩 | 亚洲欧美日本一区二区三区 | 青娱乐极品视频在线 | 奇米在线播放 | 少妇激情四射 | 成人欧美一级特黄 | 国产18精品乱码免费看 | 在线观看国产精品一区 | 中文在线日本 | 日日碰狠狠躁久久躁蜜桃 | 懂色av一区二区在线播放 | 日韩一区二区在线视频 | 久久久久久久久久久久久久久久久久久 | 日本少妇色 | 波多野结衣之潜藏淫欲 | 99久久久无码国产精品6 | 男女午夜爽爽爽 | 在线观看av中文字幕 | 少妇一级免费 | 日本少妇色视频 | 日本成人在线视频网站 | 国产二页| 精品在线观看视频 | 亚洲午夜精品久久久久久app | 黄色a级免费| 好吊视频一区二区三区四区 | 国产网友自拍视频 | 玉米地疯狂的吸允她的奶视频 | 嫩草一区二区 | 51国产偷自视频区视频 | 亚洲区成人 | 日韩在线观看网址 | 中文字幕在线观看1 | 中文字幕在线观看线人 | 美女扒开尿口给男人看 | 国产真实偷伦视频 | 免费黄色看片网站 | 激情五月av | 91pao| 超碰蜜桃 | av在线不卡一区 | 春色影视 | 自拍21区| www.男人的天堂.com | 欧美天堂在线 | 久久99精品久久久久久琪琪 | av加勒比在线 | 啪啪福利视频 | 日本一区二区三区电影在线观看 | 日本三级在线 | 国产一国产精品一级毛片 | 精品人妻少妇嫩草av无码 | 男女羞羞动态图 | 野外做受又硬又粗又大视频√ | 性欧美欧美巨大69 | 亚洲欧美网 | 少妇在线视频 | 日韩激情小说 | 日韩乱码人妻无码系列中文字幕 | 国产日产亚洲系列最新 | 中国av一级片 | 可以看毛片的网站 | 天堂网av手机版 | 色视频网站 | 69xx欧美| 黑森林av导航 | 在线1区| 国产在线一区二区 | 国产精品久久久久久免费播放 | 日韩成人精品一区二区三区 | 91超碰在线观看 | 国产精品一区二区三区四区视频 | 国产九色视频 | 波多野 在线| 超碰在线网站 | 男生裸体视频网站 | 国产午夜一级一片免费播放 | 国产一区二区三区精品在线观看 |