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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Condition 原理解析

發布時間:2024/1/18 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Condition 原理解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

流程

當調用wait 方法的時候從拿到一個最新創建的Node并加入 Condition 隊列
喚醒AQS隊列中的一個線程
判斷node是否在aqs 隊列上
如果不在的話將當前線程阻塞
當調用signal方法的時候會喚醒指定的線程 并添加當前節點到AQS隊列

wait()

public final void await() throws InterruptedException {if (Thread.interrupted())throw new InterruptedException();//添加一個節點到Condition 隊列中 如果沒有則創建放到尾節點 尾插法 節點狀態為 condtitionNode node = addConditionWaiter();//釋放當前的鎖 得到鎖的狀態 并喚醒處于 aqs隊列的一個線程long savedState = fullyRelease(node);int interruptMode = 0;//判斷一個節點是否在aqs隊列上while (!isOnSyncQueue(node)) {//如果在 park自己阻塞等待LockSupport.park(this);//判斷自己是否被中斷if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)break;}//嘗試獲取鎖if (acquireQueued(node, savedState) && interruptMode != THROW_IE)interruptMode = REINTERRUPT;//如果node 的下一個節點不是null 清理condition隊列上的節點if (node.nextWaiter != null) // clean up if cancelledunlinkCancelledWaiters();if (interruptMode != 0)//線程中斷拋異常reportInterruptAfterWait(interruptMode);}

創建Node 節點并加入Condition隊列中(單向鏈表)

如果node 是空則創建一個新的node狀態為 CONDITION并設置成尾節點
如果不是空并且節點狀態不是 CONDITION 則從鏈表中刪除 然后直接返回尾節點
如果不是空節點并且節點狀態是 CONDITION 則把尾節點的下一個節點設置成剛構建好的節點

private Node addConditionWaiter() {//拿到尾節點Node t = lastWaiter;// If lastWaiter is cancelled, clean out.//如果尾節點不等于空 并且尾節點的狀態不是 CONDITIONif (t != null && t.waitStatus != Node.CONDITION) {unlinkCancelledWaiters();t = lastWaiter;}//構建一個節點 節點狀態為 CONDITIONNode node = new Node(Thread.currentThread(), Node.CONDITION);if (t == null)//如果尾節點== null 把構建的節點設置成尾節點firstWaiter = node;else//否則把前一個節點的next指針指向構建的節點t.nextWaiter = node;//把剛構建的節點設置成尾節點lastWaiter = node;return node;}

刪除不是CONDITION狀態的節點

private void unlinkCancelledWaiters() {Node t = firstWaiter;Node trail = null;// 如果首節點不為空while (t != null) {// 獲取到下個節點Node next = t.nextWaiter;// 如果該節點的狀態不等于conditon,則該節點需要在鏈表中刪除if (t.waitStatus != Node.CONDITION) {// 該節點的下個節點設置為空,意味著垃圾回收后就回收該節點t.nextWaiter = null;// trail 為空,則把下一個節點負責給首節點if (trail == null)firstWaiter = next;else// 把下一個節點賦值給next,這樣鏈表就要繼續連接起來trail.nextWaiter = next;if (next == null)lastWaiter = trail;}// 等于condtion,把該節點賦值給尾節點elsetrail = t;// 下個一個節點賦值給t,進行下一次循環t = next;}}

喚醒AQS隊列中的一個線程

final long fullyRelease(Node node) {boolean failed = true;try {//拿當前鎖的狀態值long savedState = getState();//釋放鎖if (release(savedState)) {failed = false;return savedState;} else {throw new IllegalMonitorStateException();}} finally {if (failed)node.waitStatus = Node.CANCELLED;}} protected final boolean tryRelease(int releases) {//state -1int c = getState() - releases;if (Thread.currentThread() != getExclusiveOwnerThread())throw new IllegalMonitorStateException();boolean free = false;if (c == 0) {//如果c =0 表示當前是無鎖狀態 把線程iq清空free = true;setExclusiveOwnerThread(null);}//重新設置 statesetState(c);return free;} private void unparkSuccessor(Node node) {/** If status is negative (i.e., possibly needing signal) try* to clear in anticipation of signalling. It is OK if this* fails or if status is changed by waiting thread.*/int ws = node.waitStatus;if (ws < 0)//設置head節點的狀態為0 compareAndSetWaitStatus(node, ws, 0);/** Thread to unpark is held in successor, which is normally* just the next node. But if cancelled or apparently null,* traverse backwards from tail to find the actual* non-cancelled successor.*///拿到head節點的下一個節點Node s = node.next;//如果下一個節點為null 或者 status>0則表示是 CANCELLED 狀態//聽過尾部節點開始掃描 找到距離 head最近的一個 waitStatus<=0的節點if (s == null || s.waitStatus > 0) {s = null;for (Node t = tail; t != null && t != node; t = t.prev)if (t.waitStatus <= 0)s = t;}//如果next 節點不等于空直接喚醒這個線程if (s != null)LockSupport.unpark(s.thread);}

判斷當前節點是否在同步隊列中,返回 false 表示不在,返回true 表示如果不在,將當前線程掛起

final boolean isOnSyncQueue(Node node) {// 如果狀態是condition,證明一定不再同步隊列里,condition狀態只存在于等待隊列,在同步隊列里,node.prev是一定不為空的,因為有個head的節點if (node.waitStatus == Node.CONDITION || node.prev == null)return false;// 在等待隊列里,node.next 是等于空的,不等于空就是在同步隊列當中if (node.next != null) // If has successor, it must be on queuereturn true;// 遍歷正個同步隊列,判斷node是否在同步隊列當中return findNodeFromTail(node);}比如由于線程A調用了await 方法然后進入阻塞狀態并喚醒了處于aqs 隊列中的線程B此時線程B執行調用 signal 會喚醒處于 Condition 隊列中阻塞等待的節點

signal

public final void signal() {// 判斷當前線程是否獲取到了鎖,如果沒有拋異常if (!isHeldExclusively())throw new IllegalMonitorStateException();Node first = firstWaiter;// 如果首節點不為空,喚醒首節點if (first != null)doSignal(first);}

doSignal

private void doSignal(Node first) {do {// frist的下一個節點如果為空,就把lastWaiter設置為空if ( (firstWaiter = first.nextWaiter) == null)lastWaiter = null;// 不為空,再把first 節點從等待隊列中移除first.nextWaiter = null;} while (!transferForSignal(first) &&// 返回false,firstWaiter已經被從新賦值過了,如果不是空,進行下一次遍歷(first = firstWaiter) != null);}

transferForSignal

final boolean transferForSignal(Node node) {// 如果該節點不是condition狀態(可能編程了cancelled狀態),waitStatus=0,就會設置失敗,返回falseif (!compareAndSetWaitStatus(node, Node.CONDITION, 0))return false;// 將該節點放入到AQS隊列中Node p = enq(node);int ws = p.waitStatus;// 如果上一個節點狀態沒有被改變,也就是沒有編程cancelled狀態,就將該節點狀態設置成singal狀態if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))// 如果狀態已經是cancelled狀態,將該節點的線程掛起LockSupport.unpark(node.thread);return true;}

總結

以上是生活随笔為你收集整理的Condition 原理解析的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 国产精品11| 日韩av手机在线免费观看 | 亚洲青青草原 | 国产黄a三级三级三级看三级男男 | 日韩高清不卡在线 | 黄色网在线播放 | 邻居少妇张开双腿让我爽一夜 | 精品国产一区二区三区久久 | 中文字幕在线乱 | 欧美乱大交xxxxx潮喷 | 婷婷久久网 | 国产男女无套 | 国产精品男同 | 国产区二区 | 天堂精品在线 | 一级伦理片 | 国产午夜精品一区 | 欧美成人一区二区视频 | 91久久精品一区二区 | 国产 欧美 日韩 一区 | 亚洲国产精品99 | 曰本黄色片 | 中文字幕免费高清在线 | 天天玩天天干 | 先锋影音av资源在线 | 一区二区三区免费毛片 | 美女被爆操网站 | 精品国产一级片 | 亚洲国产免费看 | 麻豆视频软件 | 成人免费视频播放 | 国产成人精品影院 | 亚洲色图35p | 免费a级 | 亚洲妇女无套内射精 | 快播在线视频 | 日韩首页 | 亚洲福利午夜 | 免费在线观看黄 | 一本高清dvd在线播放 | free性满足hd国产精品久 | 在线观看中文字幕视频 | 精品一区二区在线视频 | 亚洲最大的成人网站 | 色图网址| 男人用嘴添女人下身免费视频 | 亚洲国产精品第一页 | 在线天堂6 | 亚洲一区二区中文 | 亚洲一二三四五 | 国产精品三级在线 | 奇米777色 | 91亚洲精品视频 | 男女日批网站 | 在线观看黄色片 | 野外吮她的花蒂高h在线观看 | 久久99热精品 | 丁香花完整视频在线观看 | 国产精品91在线观看 | 四虎1515hh.com | 国产农村妇女毛片精品久久麻豆 | 精品欧美色视频网站在线观看 | 亚洲 精品 综合 精品 自拍 | 东方伊甸园av在线 | 久国产视频 | 人妻精品久久久久中文字幕69 | 欧美乱色| 欧美激情一区二区三区在线 | 啪啪福利视频 | 永久免费AV无码网站韩国毛片 | 日日综合| 国产jzjzjz丝袜老师水多 | 亚洲视频一二三 | 日韩av一级 | 台湾性dvd性色av | 特黄老太婆aa毛毛片 | 国产欧美久久久精品免费 | 亚洲综合另类小说 | 黄在线观看免费 | 都市激情综合 | 99热99精品| 亚洲乱码国产乱码精品精大量 | 国产精品日韩欧美大师 | 四虎影视在线 | 素人一区| 99热在线国产| 精品人人人 | 福利片在线观看 | 国产一区二区免费 | 国产精品久久久久久白浆 | 男女操操操 | 无码人妻精品一区二区三区99不卡 | 好吊色视频988gao在线观看 | 加勒比波多野结衣 | 少妇性高潮视频 | 福利网站在线 | 国产一级在线观看视频 | 国产一卡二卡在线播放 | 午夜性片|