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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時(shí)間:2024/9/19 编程问答 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java await signal_java Condtion await方法和signal方法解析 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

public final void await() throws InterruptedException {

//線程已經(jīng)中斷拋出異常

if (Thread.interrupted())

throw new InterruptedException();

//加入隊(duì)列同時(shí)清理隊(duì)列中狀態(tài)不是Node.CONDITION的線程

Node node = addConditionWaiter();

int savedState = fullyRelease(node);

int interruptMode = 0;

//判斷當(dāng)前node是否在lock的隊(duì)列中

while (!isOnSyncQueue(node)) {

//不在sync隊(duì)列中,掛起。

LockSupport.park(this);

//判斷線程是否被中斷

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

break;

}

//在隊(duì)列中阻塞等待

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

interruptMode = REINTERRUPT;

//清除隊(duì)列中不是condition值的node。

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

unlinkCancelledWaiters();

//對(duì)中斷的響應(yīng)

if (interruptMode != 0)

reportInterruptAfterWait(interruptMode);

}

/**

這段代碼是將node入隊(duì)。

1、當(dāng)隊(duì)列為空的時(shí)候初始化firstWaiter和lastWaiter并且firstWaiter=lastWaiter.

2、當(dāng)隊(duì)列不為空的是時(shí)候, t.nextWaiter = node;同時(shí)更新了firstWaiter和lastWaiter的nextWaiter.

lastWaiter = node;將尾節(jié)點(diǎn)指向新加入的node。

3、這個(gè)地方關(guān)鍵在于lastWaiter和隊(duì)列中的最后一個(gè)nextWaiter持有相同的引用.

*/

private Node addConditionWaiter() {

//指向最后一個(gè)節(jié)點(diǎn)

Node t = lastWaiter;

//從最后個(gè)節(jié)點(diǎn)開(kāi)始查找,將waitStatus不等于Node.CONDITION的清除出隊(duì)列。

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的清除出隊(duì)列。

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;

}

}

//判斷該節(jié)點(diǎn)是否在sync隊(duì)列中。

final boolean isOnSyncQueue(Node node) {

//只有condition中node的waitStatus才會(huì)等于CONDITION。condition中的node也沒(méi)有prev

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

return false;

//如果node存在next節(jié)點(diǎn)那么肯定在sync隊(duì)列中

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

return true;

/*

node.prev可能不為空但是還沒(méi)有進(jìn)入到隊(duì)列中,因?yàn)镃AS執(zhí)行可能會(huì)失敗。所以繼續(xù)檢查。

*/

return findNodeFromTail(node);

}

//從隊(duì)尾開(kāi)始從前遍歷檢查該node是否在sync隊(duì)列中。

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的值設(shè)置為0然后加入sync隊(duì)列

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

//入隊(duì)

enq(node);

return true;

}

/*

如果沒(méi)有在sync隊(duì)列中自旋。

*/

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();

}

//再來(lái)看 signal()方法

public final void signal() {

if (!isHeldExclusively())

throw new IllegalMonitorStateException();

Node first = firstWaiter;

//對(duì)第一個(gè)節(jié)點(diǎn)進(jìn)行移出condition隊(duì)列加入sync隊(duì)列的操作。

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的狀態(tài)設(shè)置為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隊(duì)列

Node p = enq(node);

int ws = p.waitStatus;

//如果當(dāng)前線程的狀態(tài)是cancel掛起當(dāng)前線程

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

LockSupport.unpark(node.thread);

return true;

}

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

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

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

*/

分享到:

2017-07-31 13:48

瀏覽 165

分類:互聯(lián)網(wǎng)

評(píng)論

與50位技術(shù)專家面對(duì)面20年技術(shù)見(jiàn)證,附贈(zèng)技術(shù)全景圖

總結(jié)

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

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。