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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

5.Lock接口及其实现ReentrantLock

發布時間:2025/3/15 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 5.Lock接口及其实现ReentrantLock 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

jdk1.7.0_79

  在java.util.concurrent.locks這個包中定義了和synchronized不一樣的鎖,重入鎖——ReentrantLock,讀寫鎖——ReadWriteLock等。在已經有了內置鎖synchronized的情況下,為什么又出現了Lock顯示鎖呢?本文將以Lock作為Java并發包源碼解讀的開始.

  Lock定義最基本的加鎖和解鎖操作。

  

Lock?

void?lock();?

阻塞方式獲取鎖,直到獲取鎖后才返回?

void?locklnterruptibly();?

獲取鎖,除非當前線程被中斷?

Condition?newCondition();?

返回一個Condition實例綁定到這個鎖實例?

boolean?tryLock();?

不管是否獲取到鎖,都立即返回,非阻塞?

boolean?tryLock(long time,?TimeUnit?unit);?

在一定時間內阻塞獲取鎖?

void?unlock();?

釋放鎖?

  Lock接口有一個實現類——重入鎖ReentrantLock進入ReentrantLock類中我們就發現它對于Lock接口的實現基本上都借助于一個抽象靜態內部類Sync,該內部類繼承自AbstractQueuedSynchronizer,接著又發現兩個靜態內部類NonfairSyncFairSync,這兩個靜態內部類又是繼承自剛剛的Sync這里就要引入兩個新的概念了——公平鎖與非公平鎖。在公平的鎖上線程將按照它們發出請求的順序來獲得鎖但在非公平的鎖上則允許“插隊”:當一個線程請求非公平的鎖時,如果在發出請求的同時該鎖的狀態變為可用,那么這個線程將跳過隊列中所有的等待線程并獲得這個鎖。(《Java并發編程實戰》)

  ReentrantLock你可以稱之為重入鎖(遞歸鎖)、顯示鎖、排他鎖(獨占鎖),顯示鎖很好理解即線程在獲取鎖和釋放鎖的時候都需要代碼顯示操作。重入鎖是什么概念呢?synchronized實際上也是可重入鎖,意思就是一個線程已經持有這個鎖,當這個線程再次獲得這個鎖的時候不會被阻塞,而是使其同步狀態計數器1,這樣做的目的當然就是為了防止死鎖,當線程釋放這個鎖的時候,同步狀態計數器-1,直到遞減至0才表示這個鎖完全釋放完畢,其他線程可以獲取。那什么又是排他鎖呢?我們直到AQS定義了兩種模式下獲取鎖與釋放鎖的操作,那就是獨占模式和共享模式,所謂獨占模式就是只有一個線程能持有這個鎖,而共享模式則是這個鎖可以由多個線程所持有。例如ReebtrabtReadWriteLock的讀鎖就能由多個線程所持有。在知道了ReentrantLock的特性之后,我們再來看它其內部實現。?

  在前兩節解析AQS的時候我們就提到,AQS所提供的同步器是實現鎖的基礎框架,固然ReentrantLock同樣也是基于AQS,而ReentrantLock并沒有直接實現AQS抽象類,而是將在其內部定義一個Sync內部類來聚合AQS,這樣聚合而不是繼承的目的是為了將鎖的具體實現與鎖的使用做一個隔離,鎖的使用者關心的是鎖如何才能被正確使用,而鎖的實現者關心的是鎖如何基于AQS被正確的實現。先討論ReentrantLock$Sync抽象內部類在討論前先回顧一下能夠被子類重寫的AQS方法有哪些:?

  

AbstractQueuedSynchronizer?

protected?boolean?tryAcquire(int?arg)?

子類可實現在獨占模式下獲取同步狀態的具體方法。?

protected?boolean?tryRelease(int?arg)?

子類可實現在獨占模式下釋放同步狀態的具體方法。?

protected?int?tryAcquireShared(int?arg)?

子類可實現在共享模式下獲取同步狀態的具體方法。?

protected?int?tryReleaseShared()?

子類可實現在共享模式下釋放同步狀態的具體方法。?

protected?boolean?isHeldExclusively()?

當前同步器是否在獨占模式下被線程占用,一般表示該方法是否被當前線程所獨占。?

  通過查看ReentrantLock$Sync的源碼可知,Sync一共對AQS重寫了這么幾個方法:?

  protected final boolean tryRelease(int release) protected final boolean isHeldExclusively()

  為什么Sync只重寫了這兩個方法呢?實際上在ReentrantLock的內部還有另外兩個內部類NonfairSync非公平鎖和FairSync公平鎖,這兩個內部類是Sync的具體實現,很顯然能夠得出,對于鎖的獲取非公平鎖和公平鎖的實現是不一樣的,而對于鎖的釋放兩者均是相同實現。針對ReentrantLock的非公平鎖和公平鎖接下來我們來一一探討他們的不同點和相同點。?

  ReentrantLock定義了一個成員變量——sync,并且他提供了兩個構造方法,其默認無參構造方法創建的是非公平鎖,而有參的構造方法則傳入一個boolean類型來決定構造一個公平鎖還是非公平鎖。?

public class ReentrantLock implements Lock { private final Sync sync; public ReentrantLock() { sync = new NofairSync(); } public ReentrantLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync(); } …… }

  1.lock()

  針對開篇提到的Lock接口定義的方法,我們先來看ReentrantLockLock#lock的實現:?

public class ReentrantLock implements Lock { …… public void lock() { sync.lock(); }   …… }

  這個方法是抽象內部類定義的一個抽象方法,從命名可以看到這個類實際上就是AQSacquire獲取鎖的具體實現,在這里我們能看到非公平鎖和公平鎖對獲取鎖的不同實現,我們先來看非公平鎖對Sync#lock的實現:?

static final class NonfairSync extends Sync { final void lock() { if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); } protected final boolean tryAcquire(int acquire) {//在ReentrantLock$NonFairLock才終于看到了對AbstractQueuedSynchronizer#tryAcquire的具體實現。 return nonfairTryAcquire(acquires);//而tryAcquire的實現實際上又是在其父類ReentrantLock$Lock中實現的,好像有點繞,一會子類實現,一會父類實現。可以先這么來理解,既然它把tryAcquire的具體實現又定義在了父類,那說明這一定是父類對公共方法的抽取(Extract Method),其他地方一定有用到nonfairTryAcquire方法,不然JDK的作者不會閑的蛋疼。 } }

  ReentrantLock$Sync中非公平鎖的獲取鎖的實現?

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; }

  我們說回ReentrantLock$NonFairLock非公平鎖的lock阻塞獲取鎖的實現,在調用非公平鎖的lock方法時,就會首先進行“搶鎖”操作,也就是compareAndSetState這個方法是利用的CAS底層方法看能否搶占到鎖,而不是按照先后獲取獲取鎖的方式放到同步隊列中獲取鎖,公平鎖就是這樣。既然說到了公平鎖獲取鎖的方式,我們不妨和ReentrantLock$FairLock作一個對比:?

static final class FairSync extends Sync { inal void lock() { acquire(1); } protected final boolean tryAcquire(int acquires) {//在ReentrantLock$NonFairLock我們看到它老老實實的實現了AQS定義的tryAcquire方法,而沒有調用父類的方法,從這里我們也基本能推斷在ReentrantLock中沒有其他地方會引用到這個方法。 final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (!hasQueuedPredecessors() && compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) throw new Error(“Maximum lock count exceeded”); setState(nextc); return true; }     return false; } }

  從公平鎖(nonfairTryAcquire)公平鎖(tryAcquire)的兩個方法對比可知:公平鎖在獲取鎖的時候首先會判斷當前線程是否有前驅節點已經在隊列中等待,如果有返回true,則不進行獲取鎖的操作,這一點就是和公平鎖最大的區別,只有當前線程沒有前驅節點才獲取鎖。ReentrantLock默認構造非公平鎖,而實際上用得最多的也是非公平鎖,公平鎖從一定程度上能防止“饑餓”,但非公平鎖在性能上卻優于公平鎖,我們做以下試驗得知的確如此(詳細試驗過程《【試驗局】ReentrantLock中非公平鎖與公平鎖的性能測試》)?

  2.lockInterruptibly()

這個方法和lock方法的區別就是,lock會一直阻塞下去直到獲取到鎖,而lockInterruptibly則不一樣,它可以響應中斷而停止阻塞返回。ReentrantLock對其的實現是調用的Sync的父類AbstractQueuedSynchronizer#acquireInterruptibly方法:?

//ReentrantLock#lockInterruptibly public void lockInterruptibly() throws InterruptedException { sync.acquireInterruptibly(1);//因為ReentrantLock是排它鎖,故調用AQS的acquireInterruptibly方法 } //AbstractQueuedSynchronizer#acquireInterruptibly public final void acquireInterruptibly(int arg) throws InterruptedException{ if (Thread.interrupted()) //線程是否被中斷,中斷則拋出中斷異常,并停止阻塞 throw new InterruptedException; if (!tryAcquire(arg)) //首先還是獲取鎖,具體參照上文 doAcquireInterruptibly(arg);//獨占模式下中斷獲取同步狀態 }?

  通過查看doAcquireInterruptibly的方法實現不難發現它和acquireQueued大同小異,前者拋出異常,后者返回boolean。具體實在不再討論,參照源碼以及《2.從AbstractQueuedSynchronizer(AQS)說起(1)——獨占模式的鎖獲取與釋放》。?

  3.tryLock()?

  此方法為非阻塞式的獲取鎖,不管有沒有獲取鎖都返回一個boolean值。?

//ReentrantLock#tryLock public boolean tryLock() { return sync.nonfairTryAcquire(1); }

  可以看到它實際調用了Sync#nonfairTryAcquire非公平鎖獲取鎖的方法,這個方法我們在上文lock()方法非公平鎖獲取鎖的時候有提到,而且還特地強調了該方法不是在NonfairSync實現,而是在Sync中實現很有可能這個方法是一個公共方法,果然在非阻塞獲取鎖的時候調用的是此方法。詳細解析參照上文。?

  4.tryLock(long timeout,?TimeUnit?unit)?

此方法是表示在超時時間內獲取到同步狀態則返回true,獲取不到則返回false。由此可以聯想到AQStryAcquireNanos(int?arg, long?nanosTimeOut)方法?

//ReentrantLock#tryLock public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { return sync.tryAcquireNanos(1, unit.toNanos(timeout)); }

  果然Sync實際上調用了父類AQStryAcquireNanos方法。?

//AbstractQueuedSynchronizer#tryAcquireNanos public final boolean tryAcquireNanos(int arg, long nanosTimeout) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException();//可以看到前面和lockInterruptibly一樣 return tryAcquire(arg) || doAcquireNanos(arg, nanosTimeout);//首先也會先嘗試獲取鎖 }

  在doAcquireNanos實際也和acquireQueueddoAcquireInterruptibly差不多,不同的是增加了超時判斷。?

  關于LockReentrantLock介紹到這里,在AQS和這里遺留了一個問題——Condition,在下一節中單獨介紹Condition?

轉載于:https://www.cnblogs.com/yulinfeng/p/6906597.html

總結

以上是生活随笔為你收集整理的5.Lock接口及其实现ReentrantLock的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日韩中文在线视频 | 2022国产精品 | 亚洲AV无码成人精品区先锋 | 躁躁躁日日躁 | 国产亚洲AV无码成人网站在线 | 久久久久久久国产精品美女 | 啊av在线| 国产毛片毛片毛片 | 91精品国产乱码 | 国产视频高清 | 免费av电影网站 | 日本黄色片段 | 亚洲日本中文字幕 | 韩国一级淫一片免费放 | 亚洲一区日韩 | 激情图片网站 | 精品人妻中文无码av在线 | 人人妻人人澡人人爽精品 | 国产成年网站 | 无码人妻丰满熟妇区五十路 | 波多野结衣视频网站 | 人妻无码一区二区三区久久 | 国产精品国产精品国产专区不片 | 欧美做爰全过程免费看 | 国产精品资源网站 | 久久91亚洲精品中文字幕奶水 | 和黑帮大佬的365 | 亚洲综合免费视频 | 日韩视频免费在线播放 | 法国极品成人h版 | 五月天视频网 | 免费看欧美一级特黄a大片 国产免费的av | 欧美呦呦呦 | 久久伊人一区 | 大学生一级片 | 北条麻纪在线观看aⅴ | 实拍澡堂美女洗澡av | 无码精品一区二区免费 | 亚洲精品视频在线观看免费视频 | 黄金网站在线观看 | 欧美成人777| 免费久草视频 | 中文字幕在线影院 | h片在线观看 | 永久久久久久久 | 日韩狠狠操 | 性欧美丰满熟妇xxxx性 | 97公开免费视频 | 一区二区三区欧美 | 爆操日本美女 | 日韩在线免费av | 欧美久久久久 | 久久久亚洲国产精品 | 豆花视频成人 | 欧美黄色一级视频 | 欧美一区二区三区黄色 | 冈本视频在线观看 | 五月色婷婷综合 | 亚洲天堂网络 | 久久久三级 | 一区二区有码 | 日本人添下边视频免费 | 亚洲欧洲日韩 | 就是色| 1024精品一区二区三区日韩 | 国产精品我不卡 | 欧美专区综合 | 国产成人精品一区在线播放 | 一区二区在线看 | 东北女人啪啪ⅹxx对白 | 亚洲在线精品视频 | 欧美成人aaaaⅴ片在线看 | 亚洲精品一区二区口爆 | 亚洲黄色片网站 | 黄色大片黄色大片 | 日本伊人色 | 日本va在线观看 | 68日本xxxxxⅹxxx22 | 国产一级影片 | 国产ts在线视频 | 欧美aa一级| 日韩精品久久一区二区 | 久久国产精品久久久 | 久久精品成人av | 精品一区二区在线播放 | 欧美成人精精品一区二区频 | 日本黄网免费 | 欧美一级淫片aaaaaa | 国产美女无遮挡免费视频 | 国产精品永久在线观看 | 亚洲综合网在线观看 | 久久久久久九九九 | 欧美日韩精品久久久免费观看 | √天堂中文官网8在线 | 女人17片毛片60分钟 | 最近免费中文字幕大全免费版视频 | 亚洲自拍偷拍第一页 | 亚洲天堂久久新 | 国产精品自拍区 |