public E poll ( long timeout , TimeUnit unit ) throws InterruptedException { long nanos = unit . toNanos ( timeout ) ; final ReentrantLock lock = this . lock ; lock . lockInterruptibly ( ) ; try { for ( ; ; ) { E first = q . peek ( ) ; if ( first == null ) { if ( nanos <= 0L ) return null ; else nanos = available . awaitNanos ( nanos ) ; } else { long delay = first . getDelay ( NANOSECONDS ) ; if ( delay <= 0L ) return q . poll ( ) ; if ( nanos <= 0L ) return null ; first = null ; // don't retain ref while waiting if ( nanos < delay || leader != null ) nanos = available . awaitNanos ( nanos ) ; else { Thread thisThread = Thread . currentThread ( ) ; leader = thisThread ; try { long timeLeft = available . awaitNanos ( delay ) ; nanos -= delay - timeLeft ; } finally { if ( leader == thisThread ) leader = null ; } } } } } finally { if ( leader == null && q . peek ( ) != null ) available . signal ( ) ; lock . unlock ( ) ; } }
Retrieves and removes the head of this queue waiting if necessary until an element with an expired delay is available on this queue or the specified wait time expires .