Condition使用的一个小研究

原创
2018/11/26 16:42
阅读数 59

最近发现在项目的框架中,使用了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释放锁之后才能响应成功。

展开阅读全文
加载中

作者的其它热门文章

打赏
0
0 收藏
分享
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部