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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

java await signal_java Condtion await方法和signal方法解析

發布時間:2024/9/19 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java await signal_java Condtion await方法和signal方法解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

public final void await() throws InterruptedException {

//線程已經中斷拋出異常

if (Thread.interrupted())

throw new InterruptedException();

//加入隊列同時清理隊列中狀態不是Node.CONDITION的線程

Node node = addConditionWaiter();

int savedState = fullyRelease(node);

int interruptMode = 0;

//判斷當前node是否在lock的隊列中

while (!isOnSyncQueue(node)) {

//不在sync隊列中,掛起。

LockSupport.park(this);

//判斷線程是否被中斷

if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)

break;

}

//在隊列中阻塞等待

if (acquireQueued(node, savedState) && interruptMode != THROW_IE)

interruptMode = REINTERRUPT;

//清除隊列中不是condition值的node。

if (node.nextWaiter != null) // clean up if cancelled

unlinkCancelledWaiters();

//對中斷的響應

if (interruptMode != 0)

reportInterruptAfterWait(interruptMode);

}

/**

這段代碼是將node入隊。

1、當隊列為空的時候初始化firstWaiter和lastWaiter并且firstWaiter=lastWaiter.

2、當隊列不為空的是時候, t.nextWaiter = node;同時更新了firstWaiter和lastWaiter的nextWaiter.

lastWaiter = node;將尾節點指向新加入的node。

3、這個地方關鍵在于lastWaiter和隊列中的最后一個nextWaiter持有相同的引用.

*/

private Node addConditionWaiter() {

//指向最后一個節點

Node t = lastWaiter;

//從最后個節點開始查找,將waitStatus不等于Node.CONDITION的清除出隊列。

if (t != null && t.waitStatus != Node.CONDITION) {

unlinkCancelledWaiters();

t = lastWaiter;

}

Node node = new Node(Thread.currentThread(), Node.CONDITION);

if (t == null)

firstWaiter = node;

else

t.nextWaiter = node;

lastWaiter = node;

return node;

}

//將waitStatus不等于Node.CONDITION的清除出隊列。

private void unlinkCancelledWaiters() {

Node t = firstWaiter;

Node trail = null;

while (t != null) {

Node next = t.nextWaiter;

if (t.waitStatus != Node.CONDITION) {

t.nextWaiter = null;

if (trail == null)

firstWaiter = next;

else

trail.nextWaiter = next;

if (next == null)

lastWaiter = trail;

}

else

trail = t;

t = next;

}

}

//釋放鎖

final int fullyRelease(Node node) {

boolean failed = true;

try {

int savedState = getState();

if (release(savedState)) {

failed = false;

return savedState;

} else {

throw new IllegalMonitorStateException();

}

} finally {

if (failed)

node.waitStatus = Node.CANCELLED;

}

}

//判斷該節點是否在sync隊列中。

final boolean isOnSyncQueue(Node node) {

//只有condition中node的waitStatus才會等于CONDITION。condition中的node也沒有prev

if (node.waitStatus == Node.CONDITION || node.prev == null)

return false;

//如果node存在next節點那么肯定在sync隊列中

if (node.next != null) // If has successor, it must be on queue

return true;

/*

node.prev可能不為空但是還沒有進入到隊列中,因為CAS執行可能會失敗。所以繼續檢查。

*/

return findNodeFromTail(node);

}

//從隊尾開始從前遍歷檢查該node是否在sync隊列中。

private boolean findNodeFromTail(Node node) {

Node t = tail;

for (;;) {

if (t == node)

return true;

if (t == null)

return false;

t = t.prev;

}

}

private int checkInterruptWhileWaiting(Node node) {

return Thread.interrupted() ?

//線程被中斷了

(transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) :

0;

}

final boolean transferAfterCancelledWait(Node node) {

//將node的值設置為0然后加入sync隊列

if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {

//入隊

enq(node);

return true;

}

/*

如果沒有在sync隊列中自旋。

*/

while (!isOnSyncQueue(node))

Thread.yield();

return false;

}

private void reportInterruptAfterWait(int interruptMode)

throws InterruptedException {

if (interruptMode == THROW_IE)

throw new InterruptedException();

else if (interruptMode == REINTERRUPT)

selfInterrupt();

}

//再來看 signal()方法

public final void signal() {

if (!isHeldExclusively())

throw new IllegalMonitorStateException();

Node first = firstWaiter;

//對第一個節點進行移出condition隊列加入sync隊列的操作。

if (first != null)

doSignal(first);

}

private void doSignal(Node first) {

do {

if ( (firstWaiter = first.nextWaiter) == null)

lastWaiter = null;

first.nextWaiter = null;

} while (!transferForSignal(first) &&

(first = firstWaiter) != null);

}

final boolean transferForSignal(Node node) {

/*

* 將node的狀態設置為0.

*/

if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))

return false;

/*

* Splice onto queue and try to set waitStatus of predecessor to

* indicate that thread is (probably) waiting. If cancelled or

* attempt to set waitStatus fails, wake up to resync (in which

* case the waitStatus can be transiently and harmlessly wrong).

*/

//加入sync隊列

Node p = enq(node);

int ws = p.waitStatus;

//如果當前線程的狀態是cancel掛起當前線程

if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))

LockSupport.unpark(node.thread);

return true;

}

/**總結:condition的await方法會釋放鎖,然后掛起直到被加入sync隊列。而signal方法則是

在condition隊列中移出firstWaiter,然后將其加入sync隊列。

最后在unlock()方法喚醒線程。

*/

分享到:

2017-07-31 13:48

瀏覽 165

分類:互聯網

評論

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的java await signal_java Condtion await方法和signal方法解析的全部內容,希望文章能夠幫你解決所遇到的問題。

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