guava/src/com/google/common/collect/Queues.java
@Beta
  @CanIgnoreReturnValue
  @GwtIncompatible // BlockingQueue
  @SuppressWarnings("GoodTime") // should accept a java.time.Duration
  public static <E> int drainUninterruptibly(
      BlockingQueue<E> q,
      Collection<? super E> buffer,
      int numElements,
      long timeout,
      TimeUnit unit) {
    Preconditions.checkNotNull(buffer);
    long deadline = System.nanoTime() + unit.toNanos(timeout);
    int added = 0;
    boolean interrupted = false;
    try {
      while (added < numElements) {
        // we could rely solely on #poll, but #drainTo might be more efficient when there are
        // multiple elements already available (e.g. LinkedBlockingQueue#drainTo locks only once)
        added += q.drainTo(buffer, numElements - added);
        if (added < numElements) { // not enough elements immediately available; will have to poll
          E e; // written exactly once, by a successful (uninterrupted) invocation of #poll
          while (true) {
            try {
              e = q.poll(deadline - System.nanoTime(), TimeUnit.NANOSECONDS);
              break;
            } catch (InterruptedException ex) {
              interrupted = true; // note interruption and retry
            }
          }
          if (e == null) {
            break; // we already waited enough, and there are no more elements in sight
          }
          buffer.add(e);
          added++;
        }
      }
    } finally {
      if (interrupted) {
        Thread.currentThread().interrupt();
      }
    }
    return added;
  }
@Beta
  @CanIgnoreReturnValue
  @GwtIncompatible // BlockingQueue
  @SuppressWarnings("GoodTime") // should accept a java.time.Duration
  public static <E> int drainUninterruptibly(
      BlockingQueue<E> q,
      Collection<? super E> buffer,
      int numElements,
      long timeout,
      TimeUnit unit) {
    Preconditions.checkNotNull(buffer);
    long deadline = System.nanoTime() + unit.toNanos(timeout);
    int added = 0;
    boolean interrupted = false;
    try {
      while (added < numElements) {
        // we could rely solely on #poll, but #drainTo might be more efficient when there are
        // multiple elements already available (e.g. LinkedBlockingQueue#drainTo locks only once)
        added += q.drainTo(buffer, numElements - added);
        if (added < numElements) { // not enough elements immediately available; will have to poll
          E e; // written exactly once, by a successful (uninterrupted) invocation of #poll
          while (true) {
            try {
              e = q.poll(deadline - System.nanoTime(), TimeUnit.NANOSECONDS);
              break;
            } catch (InterruptedException ex) {
              interrupted = true; // note interruption and retry
            }
          }
          if (e == null) {
            break; // we already waited enough, and there are no more elements in sight
          }
          buffer.add(e);
          added++;
        }
      }
    } finally {
      if (interrupted) {
        Thread.currentThread().interrupt();
      }
    }
    return added;
  }
@ Beta @ CanIgnoreReturnValue @ GwtIncompatible // BlockingQueue @ SuppressWarnings ( "GoodTime" ) // should accept a java.time.Duration public static < E > int drainUninterruptibly ( BlockingQueue < E > q , Collection < ? super E > buffer , int numElements , long timeout , TimeUnit unit ) { Preconditions . checkNotNull ( buffer ) ; long deadline = System . nanoTime ( ) + unit . toNanos ( timeout ) ; int added = 0 ; boolean interrupted = false ; try { while ( added < numElements ) { // we could rely solely on #poll, but #drainTo might be more efficient when there are // multiple elements already available (e.g. LinkedBlockingQueue#drainTo locks only once) added += q . drainTo ( buffer , numElements - added ) ; if ( added < numElements ) { // not enough elements immediately available; will have to poll E e ; // written exactly once, by a successful (uninterrupted) invocation of #poll while ( true ) { try { e = q . poll ( deadline - System . nanoTime ( ) , TimeUnit . NANOSECONDS ) ; break ; } catch ( InterruptedException ex ) { interrupted = true ; // note interruption and retry } } if ( e == null ) { break ; // we already waited enough, and there are no more elements in sight } buffer . add ( e ) ; added ++ ; } } } finally { if ( interrupted ) { Thread . currentThread ( ) . interrupt ( ) ; } } return added ; }
Drains the queue as {@linkplain #drain(BlockingQueue, Collection, int, long, TimeUnit)}, but
with a different behavior in case it is interrupted while waiting. In that case, the operation
will continue as usual, and in the end the thread's interruption status will be set (no {@code
InterruptedException} is thrown).

@param q the blocking queue to be drained
@param buffer where to add the transferred elements
@param numElements the number of elements to be waited for
@param timeout how long to wait before giving up, in units of {@code unit}
@param unit a {@code TimeUnit} determining how to interpret the timeout parameter
@return the number of elements transferred
Drains the queue as { @linkplain #drain ( BlockingQueue Collection int long TimeUnit ) } but with a different behavior in case it is interrupted while waiting . In that case the operation will continue as usual and in the end the thread s interruption status will be set ( no { @code InterruptedException } is thrown ) .