code: @Override
    @Nullable
    public T acquire(long time, TimeUnit unit) {
      // If either time or unit are null, the other should also be null.
      Preconditions.checkState((time <= 0) == (unit == null));
      long endTimeMs = 0;
      if (time > 0) {
        endTimeMs = System.currentTimeMillis() + unit.toMillis(time);
      }
  
      // Try to take a resource without blocking
      T resource = mResources.poll();
      if (resource != null) {
        return resource;
      }
  
      if (mCurrentCapacity.getAndIncrement() < mMaxCapacity) {
        // If the resource pool is empty but capacity is not yet full, create a new resource.
        return createNewResource();
      }
  
      mCurrentCapacity.decrementAndGet();
      // Otherwise, try to take a resource from the pool, blocking if none are available.
      try {
        mTakeLock.lockInterruptibly();
        try {
          while (true) {
            resource = mResources.poll();
            if (resource != null) {
              return resource;
            }
            if (time > 0) {
              long currTimeMs = System.currentTimeMillis();
              // one should use t1-t0<0, not t1<t0, because of the possibility of numerical overflow.
              // For further detail see: https://docs.oracle.com/javase/8/docs/api/java/lang/System.html
              if (endTimeMs - currTimeMs <= 0) {
                return null;
              }
              if (!mNotEmpty.await(endTimeMs - currTimeMs, TimeUnit.MILLISECONDS)) {
                return null;
              }
            } else {
              mNotEmpty.await();
            }
          }
        } finally {
          mTakeLock.unlock();
        }
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new RuntimeException(e);
      }
    }
docs: Acquires an object of type {code T} from the pool.
  
  This method is like {@link #acquire()}, but it will time out if an object cannot be
  acquired before the specified amount of time.
  
  @param time an amount of time to wait, <= 0 to wait indefinitely
  @param unit the unit to use for time, null to wait indefinitely
  @return a resource taken from the pool, or null if the operation times out