日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

淺談JAVA并發之ReentrantLock

瀏覽:223日期:2022-08-11 11:10:30
目錄1. 介紹2. 源碼剖析2.1 上鎖(獲取資源)2.2 釋放資源2.3 公平鎖與非公平鎖的區別1. 介紹

淺談JAVA并發之ReentrantLock

結合上面的ReentrantLock類圖,ReentrantLock實現了Lock接口,它的內部類Sync繼承自AQS,絕大部分使用AQS的子類需要自定義的方法存在Sync中。而ReentrantLock有公平與非公平的區別,即’是否先阻塞就先獲取資源’,它的主要實現就是FairSync與NonfairSync,后面會從源碼角度看看它們的區別。

2. 源碼剖析

Sync是ReentrantLock控制同步的基礎。它的子類分為了公平與非公平。使用AQS的state代表獲取鎖的數量

abstract static class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = -5179523762034025860L; /*** Performs {@link Lock#lock}. The main reason for subclassing* is to allow fast path for nonfair version.*/ abstract void lock(); ...}

我們可以看出內部類Sync是一個抽象類,繼承它的子類(FairSync與NonfairSync)需要實現抽象方法lock。

下面我們先從非公平鎖的角度來看看獲取資源與釋放資源的原理

故事就從就兩個變量開始:

// 獲取一個非公平的獨占鎖/*** public ReentrantLock() {* sync = new ReentrantLock.NonfairSync();* }*/private Lock lock = new ReentrantLock();// 獲取條件變量private Condition condition = lock.newCondition();2.1 上鎖(獲取資源)

lock.lock()

public void lock() { sync.lock();}

static final class NonfairSync extends Sync { private static final long serialVersionUID = 7316153563782823691L; // 獲取資源 final void lock() {// 若此時沒有線程獲取到資源,直接設置當前線程獨占訪問資源。if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread());else // AQS的方法 acquire(1); } protected final boolean tryAcquire(int acquires) {// 實現在父類Sync中return nonfairTryAcquire(acquires); }}

AQS的acquire

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

// Sync實現的非公平的tryAcquirefinal 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;}

嘗試獲取資源的過程是非常簡單的,這里再貼一下acquire的流程

淺談JAVA并發之ReentrantLock

2.2 釋放資源

lock.unlock();

public void unlock() { // AQS的方法 sync.release(1);}

AQS的release

public final boolean release(int arg) { if (tryRelease(arg)) {Node h = head;if (h != null && h.waitStatus != 0) unparkSuccessor(h);return true; } return false;}

release的流程已經剖析過了,接下來看看tryRelease的實現

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

tryRelease的實現也很簡單,這里再貼一下release的流程圖

淺談JAVA并發之ReentrantLock

2.3 公平鎖與非公平鎖的區別

公平鎖與非公平鎖,即’是否先阻塞就先獲取資源’, ReentrantLock中公平與否的控制就在tryAcquire中。下面我們看看,公平鎖的tryAcquire

static final class FairSync extends Sync {private static final long serialVersionUID = -3000897897090466540L;final void lock() { acquire(1);}protected final boolean tryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) {// (2.3.1)// sync queue中是否存在前驅結點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;} }

區別在代碼(2.3.1)

hasQueuedPredecessors

判斷當前線程的前面有無其他線程排隊;若當前線程在隊列頭部或者隊列為空返回false

public final boolean hasQueuedPredecessors() { // The correctness of this depends on head being initialized // before tail and on head.next being accurate if the current // thread is first in queue. Node t = tail; // Read fields in reverse initialization order Node h = head; Node s; return h != t &&((s = h.next) == null || s.thread != Thread.currentThread());}

結合下面的入隊代碼(enq), 我們分析hasQueuedPredecessors為true的情況:

1.h != t ,表示此時queue不為空; (s = h.next) == null, 表示另一個結點已經運行了下面的步驟(2),還沒來得及運行步驟(3)。簡言之,就是B線程想要獲取鎖的同時,A線程獲取鎖失敗剛好在入隊(B入隊的同時,之前占有的資源的線程,剛好釋放資源)

2.h != t 且 (s = h.next) != null,表示此時至少有一個結點在sync queue中;s.thread != Thread.currentThread(),這個情況比較復雜,設想一下有這三個結點 A -> B C, A此時獲取到資源,而B此時因為獲取資源失敗正在sync queue阻塞,C還沒有獲取資源(還沒有執行tryAcquire)。

時刻一:A釋放資源成功后(執行tryRelease成功),B此時還沒有成功獲取資源(C執行s = h.next時,B還在sync queue中且是老二)

時刻二: C此時執行hasQueuedPredecessors,s.thread != Thread.currentThread()成立,此時s.thread表示的是B

private Node enq(final Node node) { for (;;) {Node t = tail;if (t == null) { // Must initialize if (compareAndSetHead(new Node())) // (1) 第一次初始化tail = head;} else { node.prev = t; if (compareAndSetTail(t, node)) { // (2) 設置queue的tailt.next = node; // (3)return t; }} }}

Note that 1. because cancellations due to interrupts and timeouts may occur at any time, a true return does not guarantee that some other thread will acquire before the current thread(虛假true). 2. Likewise, it is possible for another thread to win a race to enqueue after this method has returned false, due to the queue being empty(虛假false).

這位大佬對hasQueuedPredecessors進行詳細的分析,他文中解釋了虛假true以及虛假false。我這里簡單解釋一下:

1.虛假true, 當兩個線程都執行tryAcquire,都執行到hasQueuedPredecessors,都返回true,但是只有一個線程執行compareAndSetState(0, acquires)成功

2.虛假false,當一個線程A執行doAcquireInterruptibly,發生了中斷,還沒有清除掉該結點時;此時,線程B執行hasQueuedPredecessors時,返回true

以上就是淺談JAVA并發之ReentrantLock的詳細內容,更多關于JAVA并發之ReentrantLock的資料請關注好吧啦網其它相關文章!

標簽: Java
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产精品亚洲欧美日韩一区在线| 欧美在线看片| 国产欧美日韩一级| 国产精品一在线观看| 国产探花一区| 国产精品成久久久久| 毛片不卡一区二区| 日本免费久久| 亚洲色诱最新| 日韩和欧美一区二区三区| 欧美日韩国产一区二区在线观看| 国产情侣一区在线| 久久一区视频| 影视先锋久久| 婷婷成人综合| 欧美日本三区| 久久久久.com| 视频一区中文字幕精品| 最新中文字幕在线播放| 欧美日韩视频| 精品伊人久久| 一二三区精品| 日韩电影免费网址| 日韩高清电影一区| 中文国产一区| 亚洲调教视频在线观看| 91精品国产乱码久久久久久久| 成人自拍av| 久久精品九色| 青青草国产精品亚洲专区无| 免费看的黄色欧美网站| 91久久国产| 久久久久久久久99精品大| 精品理论电影在线| 亚洲精品精选| 亚洲尤物av| 日韩在线网址| 亚洲aa在线| 欧美日本一区| 久久这里只有| 精品美女久久| 国产在线|日韩| 亚洲女同一区| 亚洲午夜免费| 日韩激情综合| 国产精品网站在线看| 欧美日韩一区二区三区不卡视频 | 国产精品巨作av| 日韩1区2区3区| 国产精选一区| 国产盗摄——sm在线视频| 99tv成人| 蜜桃久久av一区| 国产精品久久免费视频| 日韩免费高清| 亚洲午夜精品久久久久久app| 欧美freesex黑人又粗又大| 亚洲精品小说| 国产免费av一区二区三区| 国产一区国产二区国产三区| 欧美高清不卡| 亚洲毛片在线免费| 国产精品嫩模av在线| 91精品国产福利在线观看麻豆| 综合亚洲视频| 国产传媒av在线| 久久先锋影音| 麻豆久久久久久| 一本色道久久精品| 久久中文字幕一区二区| 国产中文一区| 日韩精品91亚洲二区在线观看| 国内一区二区三区| 久久国产精品亚洲77777| 开心激情综合| 亚洲精品乱码久久久久久蜜桃麻豆 | 日本va欧美va瓶| 精品欧美视频| 在线综合欧美| 成人羞羞在线观看网站| 日韩精品一级中文字幕精品视频免费观看 | 人在线成免费视频| 亚洲在线观看| 日韩精品永久网址| 国产精品流白浆在线观看| 91久久国产| 欧美影院三区| 久久久久免费| 精品久久美女| 国产精品黄网站| 中文无码日韩欧| 欧洲精品一区二区三区| 国产精品2023| 国产精品视频首页| 日韩精品视频网| 日韩免费精品| 亚洲一区二区三区高清不卡| 欧美亚洲日本精品| 国产精品久久久久蜜臀| 美女精品久久| 在线国产精品一区| 日韩欧美自拍| 日韩国产一区二区三区| 精品美女在线视频| 国产精品一区二区av日韩在线| 亚洲精品一二三区区别| 日本免费久久| 日韩中文字幕高清在线观看| 水蜜桃久久夜色精品一区| 国产精品mm| 精品一区二区三区在线观看视频 | 午夜精品影院| 五月婷婷六月综合| 亚洲91视频| 91tv亚洲精品香蕉国产一区| 日韩欧美视频专区| 久久久久网站| 久久婷婷av| 午夜一级在线看亚洲| 美女精品在线观看| 亚洲一区二区三区无吗| 亚洲精品乱码日韩| 日韩激情av在线| 国产精品66| 国产日韩电影| 91精品一区二区三区综合在线爱| 伊人精品一区| 国产欧美日韩一区二区三区四区| 中文字幕在线官网| 九九综合九九| 日韩av一二三| 夜鲁夜鲁夜鲁视频在线播放| 国产在线日韩| 日韩高清一级| 久久久人人人| 亚洲va久久| 欧美aⅴ一区二区三区视频| 不卡专区在线| 亚洲在线免费| 高清不卡一区| 亚洲天堂久久| 国产欧美久久一区二区三区| 亚洲va在线| 国产九九精品| 视频一区中文| 国产乱子精品一区二区在线观看 | 青草久久视频| 国产精品久久久久久久久久10秀| 久久国产亚洲精品| 欧美日韩亚洲一区| av不卡免费看| 婷婷激情一区| 国产精品4hu.www| 日韩精品一卡二卡三卡四卡无卡| 日韩av在线播放网址| 日本不卡一二三区黄网| 午夜国产精品视频免费体验区| 国产成人精品三级高清久久91| 亚洲精品三级| 水野朝阳av一区二区三区| 午夜日韩福利| 日韩不卡一二三区| 视频精品一区二区| 欧美gv在线| 四虎4545www国产精品 | 国产一区二区三区日韩精品 | 亚洲欧洲专区| 国产一级久久| 欧美日韩高清| 久久亚洲人体| 久久精品欧洲| 久久一区国产| 国产精品久久观看| 精精国产xxxx视频在线野外| 超碰成人av| 亚洲a在线视频| 午夜国产精品视频免费体验区| 亚洲午夜在线| 亚洲影视一区| 国产精品久久国产愉拍| 精品中文字幕一区二区三区| 久久精品国产亚洲aⅴ| 正在播放日韩精品| 久久高清免费| 91精品啪在线观看国产18 | 亚洲午夜天堂| 亚洲va中文在线播放免费| 欧美成人日韩| 日韩av电影一区| 激情黄产视频在线免费观看| 激情久久婷婷| 视频一区日韩| 麻豆91小视频| 亚洲福利免费| 日韩成人午夜精品| 一区二区三区四区精品视频| 亚洲欧美日本日韩| 国产精品视频一区二区三区综合| 国产精品社区| 蜜桃视频一区二区|