最近发现在项目的框架中,使用了Condition来进行线程间的通信。并且使用的方式是如下的方式。
...................Thread1........................
try{
Lock.lock();
Condition.await(long,TimeUnit);
}catch(InterruptException){
log.error("...........");
}finally(){
lock.unlock();
}
.................Thread2..........................
try{
Lock.lock();
doBussiness();
Condition.signal();
}catch(Exception e){
log.error("...........");
}finally(){
lock.unlock();
}
一开始我的印象是Condition在超时之后,或者中断之后,应该会立马走到异常,但是finally中怎么会释放锁呢?这个应该会释放失败?
跟踪下源码
public final boolean await(long time, TimeUnit unit)
throws InterruptedException {
if (unit == null)
throw new NullPointerException();
long nanosTimeout = unit.toNanos(time);
if (Thread.interrupted())
throw new InterruptedException();
Node node = addConditionWaiter();
int savedState = fullyRelease(node);
long lastTime = System.nanoTime();
boolean timedout = false;
int interruptMode = 0;
while (!isOnSyncQueue(node)) {
if (nanosTimeout <= 0L) {
timedout = transferAfterCancelledWait(node);
break;
}
if (nanosTimeout >= spinForTimeoutThreshold)
LockSupport.parkNanos(this, nanosTimeout);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
long now = System.nanoTime();
nanosTimeout -= now - lastTime;
lastTime = now;
}
//这里是最重要的 不管你是否是中断还是超时 都需要重新获取锁
if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
interruptMode = REINTERRUPT;
if (node.nextWaiter != null)
unlinkCancelledWaiters();
if (interruptMode != 0)
reportInterruptAfterWait(interruptMode);
return !timedout;
}
所以,await()中退出的时候,必须获取Lock的排它锁,所以Await()方式超时或者中断并不能马上响应,还是需要等待Thread2释放锁之后才能响应成功。