本文共 2105 字,大约阅读时间需要 7 分钟。
DelayQueue实现Leader-Folloer pattern 1、当存在多个take线程时,同时只生效一个,即,leader线程 2、当leader存在时,其它的take线程均为follower,其等待是通过condition实现的 3、当leader不存在时,当前线程即成为leader,在delay之后,将leader角色释放还原 4、最后如果队列还有内容,且leader空缺,则调用一次condition的signal,唤醒挂起的take线程,其中之一将成为新的leader 5、最后在finally中释放锁/** * Retrieves and removes the head of this queue, waiting if necessary * until an element with an expired delay is available on this queue. * * @return the head of this queue * @throws InterruptedException {@inheritDoc} */ public E take() throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { for (;;) { E first = q.peek(); if (first == null) available.await(); /*队列为空则让当前线程在condition available上等待*/ else { long delay = first.getDelay(TimeUnit.NANOSECONDS); if (delay <= 0) /*超时时间已到,直接从队列中取出元素,线程返回。*/ return q.poll(); else if (leader != null) /*超时时间未到,且leader不为空(有线程正在处理),则当前调用线程在condition available上等待*/ available.await(); else { Thread thisThread = Thread.currentThread(); leader = thisThread; /*超时时间未到,且leader为空,则当前调用线程成为leader线程,leader是DelayQueue的private成员*/ try { available.awaitNanos(delay); /*leader线程在condition available挂起直到超时时间满足,leader线程释放锁(atomically release the associated lock)*/ } finally { /*使用try finally保证finally中的语句务必执行*/ if (leader == thisThread) /*问题:finally是在线程唤醒,重新竞争到锁,然后从 awaitNanos 继续执行,最后执行到finally*/ leader = null; } } } } } finally { if (leader == null && q.peek() != null) /*队列中有数据,且leader为空,则需要唤醒一下condition available等待队列上的线程,重新竞争锁,然后从挂起处继续执行*/ available.signal(); lock.unlock(); /*最后释放锁*/ } }
转载地址:http://kvhii.baihongyu.com/