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

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

Java并發編程之淺談ReentrantLock

瀏覽:31日期:2022-08-11 17:57:45
目錄一、首先看圖二、lock()跟蹤源碼2.1 非公平鎖實現2.1.1 tryAcquire(arg)2.1.2 acquireQueued(addWaiter(Node.EXCLUSIVE), arg)2.2 公平鎖實現2.2.1 tryAcquire(arg)一、首先看圖

Java并發編程之淺談ReentrantLock

二、lock()跟蹤源碼

Java并發編程之淺談ReentrantLock

這里對公平鎖和非公平鎖做了不同實現,由構造方法參數決定是否公平。

public ReentrantLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync();}2.1 非公平鎖實現

static final class NonfairSync extends Sync { private static final long serialVersionUID = 7316153563782823691L;final void lock() {if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread());else acquire(1); } protected final boolean tryAcquire(int acquires) {return nonfairTryAcquire(acquires); }}

代碼量很少。首先compareAndSetState(0, 1)通過CAS(期望值0,新值1,內存值stateOffset)

如果修改成功,即搶占到鎖,setExclusiveOwnerThread(Thread.currentThread());將AQS中的變量exclusiveOwnerThread設置為當前搶占到鎖的線程,也就是圖中的ThreadA。 若沒有搶占成功,證明此時鎖被占用,執行方法acquire(1);。

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

這里主要看兩個方法tryAcquire(arg)和acquireQueued(addWaiter(Node.EXCLUSIVE), arg)。當滿足if條件后,會給當前線程標記一個interrupt狀態。

2.1.1 tryAcquire(arg)

這個方法又有多個實現。這里看NonfairSync非公平鎖。

Java并發編程之淺談ReentrantLock

protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires);}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; }

在這個方法中,還不死心,首先會判斷下AQS中的state是否為0,為0也就是說距離上次嘗試獲取鎖到現在準備進入隊列(雙向鏈表)中這段時間內,鎖已經被釋放,可以重新CAS嘗試獲取鎖。

如果當前鎖還是被持有狀態,就是state!=0,就會判斷,當前線程是不是當前持有鎖的線程exclusiveOwnerThread,如果是,則state+1,從這里可以看出state表示的是重入次數。

全部不滿足,返回false。

2.1.2 acquireQueued(addWaiter(Node.EXCLUSIVE), arg)

addWaiter

private Node addWaiter(Node mode) { Node node = new Node(Thread.currentThread(), mode); // Try the fast path of enq; backup to full enq on failure Node pred = tail; if (pred != null) {node.prev = pred;if (compareAndSetTail(pred, node)) { pred.next = node; return node;} } enq(node); return node;}

tryAcquire(arg)返回false,證明當前線程還是沒有獲取到鎖。那么就要進入隊列等待了,首先addWaiter方法,將當前線程封裝成一個Node,如果pred不為空,則將當前節點做鏈表的尾部插入,同時為了防止在此期間前序節點已經不在隊列中了,也會運用CAS操作來執行(期望值pred,新值node,內存值tailOffset)。

如果前序節點為空,或者在CAS時發現前序節點已經不存在了,則重新構建鏈表,將當前節點封裝的Node,加入到鏈表當中。

private Node enq(final Node node) { for (;;) {Node t = tail;if (t == null) { // Must initialize if (compareAndSetHead(new Node()))tail = head;} else { node.prev = t; if (compareAndSetTail(t, node)) {t.next = node;return t; }} }}

加入完成后,返回當前node節點,進入acquireQueued方法。

acquireQueued

final boolean acquireQueued(final Node node, int arg) { boolean failed = true; try {boolean interrupted = false;for (;;) {//獲取到當前node節點的上一個節點 final Node p = node.predecessor(); //如果當前的上個節點就是頭節點,會再次嘗試獲取鎖 if (p == head && tryAcquire(arg)) { //獲取成功,將當前節點置空,并成為新的頭節點setHead(node);//這個p已經沒用了,防止內存泄漏,直接指向null,下次GC時回收p.next = null; // help GC//不需要取消failed = false;//return false,不需要中斷當前線程return interrupted; } if (shouldParkAfterFailedAcquire(p, node) &&parkAndCheckInterrupt())interrupted = true;} } finally {if (failed) cancelAcquire(node); }}

這里是一個自旋操作,首先拿到當前線程封裝節點的上一個節點,如果滿足第一個if條件if (p == head && tryAcquire(arg)),證明上個節點為頭節點,則此時當前線程也會再次嘗試獲取鎖,獲取鎖成功,證明此時沒有別的線程在隊列中了,則將當前node清空并設置為頭節點,返回不需要中斷當前線程。

在第二個if條件中if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt())。走到這里證明當前線程不是第一個線程節點,或者沒有搶占到鎖,shouldParkAfterFailedAcquire這個方法見名知意,在搶占失敗后是否需要park阻塞,里面主要是用于清理雙向鏈表中被取消的節點線程和未被阻塞的節點線程。

private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) { int ws = pred.waitStatus;//獲取前置節點的等待狀態 if (ws == Node.SIGNAL)//前置節點的等待狀態為-1,表示前置節點在隊列中阻塞,那么當前節點也需要被阻塞在隊列中return true; if (ws > 0) {//前置節點等待狀態大于0,此前置節點已經被取消,循環遍歷清除所有已被取消的節點。do { node.prev = pred = pred.prev;} while (pred.waitStatus > 0);pred.next = node; } else {//前置節點等待狀態小于等于0,且不等于-1,也就是沒有被阻塞也沒有被取消//則將前置節點設置為阻塞狀態。compareAndSetWaitStatus(pred, ws, Node.SIGNAL); } return false;} 前置節點的等待狀態為-1,表示前置節點在隊列中阻塞,那么當前節點也需要被阻塞在隊列中 前置節點等待狀態大于0,此前置節點已經被取消,循環遍歷清除所有已被取消的節點。 前置節點等待狀態小于等于0,且不等于-1,也就是沒有被阻塞也沒有被取消。則將前置節點設置為阻塞狀態。

到這里,基于非公平鎖的實現結束。

2.2 公平鎖實現

公平鎖和樂觀鎖的區別就在于,非公平鎖acquire(1)前會先嘗試獲取鎖,公平鎖直接acquire(1)。

static final class FairSync extends Sync {private static final long serialVersionUID = -3000897897090466540L;final void lock() { acquire(1);}}2.2.1 tryAcquire(arg)

在tryAcquire中也和非公平鎖有一定的區別。在當前鎖沒有被占有時。非公平鎖不用考慮目前AQS隊列中的排隊情況,直接通過CAS嘗試獲取鎖。公平鎖會看目前隊列的狀態,再來決定是嘗試占有鎖還是在隊列中等待。

protected final boolean tryAcquire(int acquires) { 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;}

到此這篇關于Java并發編程之淺談ReentrantLock的文章就介紹到這了,更多相關Java ReentrantLock內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Java
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
久久激情中文| 国产中文欧美日韩在线| 久久久久久黄| 日韩国产一区二区| 韩日一区二区| 国产成人精品一区二区三区免费 | 久久免费视频66| 日本成人在线一区| 欧美日韩一区二区三区四区在线观看| 亚洲精品看片| 国产精品色在线网站| 久久成人高清| 日本免费一区二区三区四区| 久久久久国产精品一区三寸| 91高清一区| 一区二区精品| 欧美日本二区| 九九久久国产| 在线观看精品| 国产精品免费看| 日韩精品久久理论片| 久久av日韩| 毛片在线网站| 免费视频一区三区| 亚洲精品乱码久久久久久蜜桃麻豆| 日韩中文字幕无砖| 精品国产一区二区三区性色av| 人人草在线视频| 国产精品7m凸凹视频分类| 视频一区二区不卡| 国产欧美午夜| 日韩成人综合| 日韩在线播放一区二区| 国产精品视频首页| 深夜视频一区二区| 蜜臀91精品一区二区三区| 国产欧美日韩亚洲一区二区三区| 精品午夜久久| 伊人久久成人| 欧美黄页在线免费观看| 成人看片网站| 日韩精品久久久久久久软件91| 精品一区二区三区的国产在线观看| 99久久亚洲精品| 婷婷久久免费视频| 色综合五月天| 日韩在线一区二区| 精品五月天堂| 国产视频久久| 久久三级毛片| 久久亚洲二区| 国产精品成人a在线观看| 国产一区91| 九九久久国产| 亚洲伊人精品酒店| 日韩国产欧美| 日本电影久久久| 久久亚洲国产| 国产精品综合色区在线观看| 99久久激情| 国产精品扒开腿做爽爽爽软件| 久久精品国语| 国产极品一区| 久久亚洲欧洲| 国产一区二区三区四区五区| 亚洲欧美视频| 高清av一区| 亚洲精品欧洲| 日本一区二区高清不卡| 亚洲一区二区小说| 久久精品99久久无色码中文字幕| 久久国产尿小便嘘嘘| 91精品福利| www.九色在线| 日韩精品亚洲一区二区三区免费| 波多野结衣一区| 国产一区二区三区四区| 日本一区二区三区视频在线看| 99久久九九| 国产一区二区三区精品在线观看| 综合亚洲色图| 天堂网在线观看国产精品| 日本亚洲视频在线| 日韩午夜av在线| 欧美天堂视频| 久久99国产精品视频| 亚洲精选久久| 夜夜嗨一区二区三区| 成人精品国产亚洲| 国产精品一卡| 日本va欧美va精品| 中文字幕日韩欧美精品高清在线| 亚洲香蕉网站| 伊人久久高清| 91亚洲国产高清| 精品中文字幕一区二区三区四区| 欧美日韩午夜电影网| 水蜜桃久久夜色精品一区的特点| 精品国产欧美日韩| 欧美精品aa| 国产亚洲一区二区三区啪| 免费精品视频在线| 五月天久久网站| 亚洲性色视频| 日韩三区在线| 日韩欧美午夜| 国产一区二区三区亚洲综合| 国产精品美女午夜爽爽| 视频一区中文字幕精品| 巨乳诱惑日韩免费av| 日韩视频精品在线观看| 欧美精品一区二区三区精品| 久久久久.com| 都市激情国产精品| 国产成人精品福利| 国产精品99在线观看| 精品久久不卡| 精品日韩一区| 老牛国内精品亚洲成av人片| 国产精品密蕾丝视频下载| 国产欧美自拍| 欧美aa在线视频| 久久久久黄色| 欧美激情精品| 成人污污视频| 日韩电影免费在线观看| 三上悠亚国产精品一区二区三区| 日韩不卡免费高清视频| 黑人精品一区| 欧美日韩中文一区二区| 国产综合精品一区| 黄色成人在线网址| 亚洲欧美日本视频在线观看| 免费看日韩精品| 日本视频一区二区| 欧美国产先锋| 国产粉嫩在线观看| 美女少妇全过程你懂的久久| 美女国产一区| 日本视频一区二区| 久久精品国产999大香线蕉| 国产+成+人+亚洲欧洲在线| 欧美日韩在线观看首页| 日韩一区电影| 亚洲在线观看| 日韩av不卡一区二区| 麻豆精品新av中文字幕| 不卡专区在线| 亚洲一级影院| 亚洲永久精品唐人导航网址| 久久国产麻豆精品| 亚洲国产福利| 99视频+国产日韩欧美| 亚洲精品一级| 韩国女主播一区二区三区| 亚洲va在线| 蜜桃av一区二区在线观看| 国产亚洲电影| 成人台湾亚洲精品一区二区| 99久久99久久精品国产片果冰 | 制服诱惑一区二区| 亚洲精品乱码日韩| 久久久久亚洲精品中文字幕| 免费污视频在线一区| 99xxxx成人网| 国产欧美日韩一区二区三区在线| 国产成人精品一区二区三区在线| 国产在线不卡| 欧美在线黄色| 亚洲最新无码中文字幕久久 | 成人在线免费观看网站| 欧美日韩国产高清电影| 日韩黄色在线观看| av资源亚洲| 免费看黄色91| 麻豆传媒一区二区三区| 999久久久精品国产| 综合激情网站| 激情国产在线| 亚洲美女久久| 国产精品久久久久久久久久10秀 | 蜜臀精品久久久久久蜜臀| 久久久精品区| 激情欧美一区二区三区| 日韩欧美在线精品| 日韩精品水蜜桃| 欧美一区二区三区久久精品| 亚洲成人av观看| 欧美亚洲国产日韩| 国产精品蜜芽在线观看| 蜜芽一区二区三区| 国产一区二区三区探花| 日韩在线观看一区二区| 国产suv精品一区二区四区视频| 9久re热视频在线精品| 久久99蜜桃| 免费看欧美美女黄的网站| 97精品视频在线看| 日韩影院精彩在线| 黄色aa久久|