public boolean offer(E e,long timeout,TimeUnit unit) throws InterruptedException {
  if (e == null)   throw new NullPointerException();
  long nanos=unit.toNanos(timeout);
  int c=-1;
  final ReentrantLock putLock=this.putLock;
  final AtomicInteger count=this.count;
  putLock.lockInterruptibly();
  try {
    while (count.get() == capacity) {
      if (nanos <= 0)       return false;
      nanos=notFull.awaitNanos(nanos);
    }
    enqueue(new Node<E>(e));
    c=count.getAndIncrement();
    if (c + 1 < capacity)     notFull.signal();
  }
  finally {
    putLock.unlock();
  }
  if (c == 0)   signalNotEmpty();
  return true;
}

public boolean offer ( E e , long timeout , TimeUnit unit ) throws InterruptedException { if ( e == null ) throw new NullPointerException ( ) ; long nanos = unit . toNanos ( timeout ) ; int c = - 1 ; final ReentrantLock putLock = this . putLock ; final AtomicInteger count = this . count ; putLock . lockInterruptibly ( ) ; try { while ( count . get ( ) == capacity ) { if ( nanos <= 0 ) return false ; nanos = notFull . awaitNanos ( nanos ) ; } enqueue ( new Node < E > ( e ) ) ; c = count . getAndIncrement ( ) ; if ( c + 1 < capacity ) notFull . signal ( ) ; } finally { putLock . unlock ( ) ; } if ( c == 0 ) signalNotEmpty ( ) ; return true ; }
inserts the specified element at the tail of this queue , waiting if necessary up to the specified wait time for space to become available .
