sleep和wait有什么區別?大家都說是sleep不會釋放鎖,wait會釋放鎖。一直都不是很理解。最近在看AQS代碼,才找到一些蛛絲馬跡。AQS的await和wait實現思想類似,釋放當前占有的鎖,讓其他線程繼續獲取鎖。等適合機會喚醒后再重新占有鎖。
await方法有fullyRelease的方法 1.先將線程插入等待隊列; 2.釋放當前的占有的資源,即釋放鎖; 3.讓當前線程停止,等待喚醒; 4.喚醒后繼續爭搶鎖。
public final void await() throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); Node node = addConditionWaiter(); int savedState = fullyRelease(node); int interruptMode = 0; while (!isOnSyncQueue(node)) { LockSupport.park(this); if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) break; } if (acquireQueued(node, savedState) && interruptMode != THROW_IE) interruptMode = REINTERRUPT; if (node.nextWaiter != null) // clean up if cancelled unlinkCancelledWaiters(); if (interruptMode != 0) reportInterruptAfterWait(interruptMode); }fullyRelease先保存當前資源,然后釋放資源。等待適合時機再恢復當前的狀態。
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; } }跟進去release方法看看,執行tryRelease,然后unparkSuccessor,就是喚醒后繼線程。因此await會釋放其占有的資源,換句話說就是釋放其占有的鎖。讓其他線程有機會獲取鎖。
public final boolean release(int arg) { if (tryRelease(arg)) { Node h = head; if (h != null && h.waitStatus != 0) unparkSuccessor(h); return true; } return false; }新聞熱點
疑難解答