code: @Override
    public void release(T resource) {
      // We don't need to acquire mLock here because the resource is guaranteed not to be removed
      // if it is not available (i.e. not in mAvailableResources list).
      if (!mResources.containsKey(resource)) {
        throw new IllegalArgumentException(
            "Resource " + resource.toString() + " was not acquired from this resource pool.");
      }
      ResourceInternal<T> resourceInternal = mResources.get(resource);
      resourceInternal.setLastAccessTimeMs(mClock.millis());
      try {
        mLock.lock();
        mAvailableResources.addFirst(resourceInternal);
        mNotEmpty.signal();
      } finally {
        mLock.unlock();
      }
    }
docs: Releases the resource to the pool. It expects the resource to be released was acquired from
  this pool.
  {@link DynamicResourcePool#release(Object)} and {@link DynamicResourcePool#acquire()} must be
  paired. Do not release the resource acquired multiple times. The behavior is undefined if
  that happens.
  
  @param resource the resource to release