多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > 互聯網 > 聊聊高并發(十三)實現幾種自旋鎖(六)

聊聊高并發(十三)實現幾種自旋鎖(六)

來源:程序員人生   發布時間:2014-11-17 08:58:38 閱讀次數:1901次

聊聊高并發(101)實現幾種自旋鎖(5) 給出了限時有界隊列鎖的lock和unlock實現,這篇給出tryLock的實現


tryLock比lock略微復雜1點,要處理超時的情況。超時有幾種情況:

1. 第1步在等待隊列還沒有取得節點的時候超時,直接返回false便可

2. 第2步在等待隊列已取得節點但是還沒有加入工作隊列時超時,把節點狀態可以直接改成FREE給后續線程使用,然后返回false便可

3. 第3步在前1個節點的狀態上自旋時超時,將節點的preNode設置成前1個節點,然后將節點狀態改成ABORTED,然后返回便可。后續節點在該節點的狀態自旋,當發現這個先驅節點已是ABORTED了,后續節點就把先驅節點的preNode上自旋,然后把這個節點狀態改成FREE,給其他線程使用。

QNode的preNode字段只有當在工作隊列中超時的時候才會被設置,也只被后續節點使用1次,而且該域總是先設置,再使用,所以也不需要顯式地在其他地方清空該域。

public boolean trylock(long time, TimeUnit unit) throws InterruptedException { long startTime = System.currentTimeMillis(); long duration = TimeUnit.MILLISECONDS.convert(time, unit); long expectedTime = startTime + duration; Backoff backoff = new Backoff(MIN_BACKOFF, MAX_BACKOFF); QNode node = waitings[random.nextInt(SIZE)]; // 第1步: 先取得數組里的1個Node,并把它的狀態設置為WAITING,否則就自旋 GETNODE: while (true) { while (node.state.get() != State.FREE) { // 由于釋放鎖時只是設置了State為RELEASED,由后繼的線程來設置RELEASED為FREE // 如果該節點已是隊尾節點了并且是RELEASED,那末可以直接可以被使用 // 獲得當前原子援用變量的版本號 int[] currentStamp = new int[1]; QNode tailNode = tail.get(currentStamp); if (tailNode == node && (tailNode.state.get() == State.ABORTED || tailNode.state.get() == State.RELEASED)) { QNode preNode = null; // 如果最后1個節點是ABORTED狀態,就把tail指向它的前1個節點 if(tailNode.state.get() == State.ABORTED){ preNode = tailNode.preNode; } if (tail.compareAndSet(tailNode, preNode, currentStamp[0], currentStamp[0] + 1)) { node.state.set(State.WAITING); break GETNODE; } } } if (node.state.compareAndSet(State.FREE, State.WAITING)) { break; } try { backoff.backoff(); } catch (InterruptedException e) { return false; } if (timeout(expectedTime, System.currentTimeMillis())) { return false; } } // 第2步加入隊列 int[] currentStamp = new int[1]; QNode preTailNode = null; do { preTailNode = tail.get(currentStamp); // 如果未加入隊列前超時,就設置node狀態為FREE,給后續線程使用 if (timeout(expectedTime, System.currentTimeMillis())) { node.state.set(State.FREE); return false; } } // 如果沒加入隊列,就1直自旋 while (!tail.compareAndSet(preTailNode, node, currentStamp[0], currentStamp[0] + 1)); // 第3步在前1個節點自旋,如果前1個節點為null,證明是第1個加入隊列的節點 if (preTailNode != null) { // 在前1個節點的狀態自旋 State s = preTailNode.state.get(); while (s != State.RELEASED) { if(s == State.ABORTED){ QNode temp = preTailNode; preTailNode = preTailNode.preNode; // 可以釋放該節點 temp.state.set(State.FREE); } if (timeout(expectedTime, System.currentTimeMillis())) { node.preNode = preTailNode; node.state.set(State.ABORTED); return false; } s = preTailNode.state.get(); } // 設置前1個節點的狀態為FREE,可以被其他線程使用 preTailNode.state.set(State.FREE); } // 將線程的myNode指向取得鎖的node myNode.set(node); return true; }


生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------

上一篇 OCP47:155

下一篇 C++之tinyXML使用

分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 在线视频中文字幕 | 亚洲手机在线手机观看高清hd | 日韩福利在线 | 国产69精品久久久久妇女 | a级亚洲片精品久久久久久久 | 成人亚洲国产精品久久 | 亚洲精品第一 | 波多野结衣四虎精品影库 | 欧美 日韩 亚洲另类专区 | 亚洲精品免费在线观看 | 99国产精品久久久久久久成人热 | 日本人与物videos另类 | 亚洲成人福利在线观看 | 国产精品亚洲欧美日韩久久 | 亚洲欧美高清视频 | 午夜激情啪啪 | 精品久久久久久国产免费了 | 国产精品日韩一区二区三区 | 国产欧美另类 | 色成人亚洲 | 伊人一本之道 | 国产亚洲毛片在线 | 国产人成久久久精品 | 国内精品视频九九九九 | 亚洲综色| 日本青草视频 | 欧美刺激性色黄大片18 | 99精品国产在这里白浆 | 国产亚洲欧美日韩俺去了 | 男男gaygays亚洲中国 | 亚洲成人福利网站 | 亚洲国产天堂久久综合图区 | 亚洲 欧美 字幕 一区 在线 | 羞羞视频免费入口网站 | www.日本在线播放 | 精品在线一区二区三区 | 最新国产中文字幕 | 欧美性生话 | 免费观看老外特级毛片 | 欧美激情性xxxxx | 免费黄色福利 |