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;
}