code: synchronized void checkEvict() throws IOException {
      if (cacheSize.get() < cacheSizeMax) {
        return;        // nothing to do, plenty of free space
      }
  
      // Only one thread should be doing the eviction. Do not block
      // current thread, it is ok to oversubscribe the cache size
      // temporarily.
      if (evictionInProgress) {
        return;
      }
  
      // record the fact that eviction has started.
      evictionInProgress = true;
  
      try {
        // if the cache has reached a threshold size, then free old entries.
        long curSize = cacheSize.get();
  
        // how much to evict in one iteration
        long targetSize = cacheSizeMax -
                          (cacheSizeMax * cacheEvictPercent)/100;
  
        if (LOG.isDebugEnabled()) {
          LOG.debug("Cache size " + curSize + " has exceeded the " +
                    " maximum configured cacpacity " + cacheSizeMax +
                    ". Eviction has to reduce cache size to " +
                    targetSize);
        }
  
        // sort all entries based on their accessTimes
        Collection<CacheEntry> values = cacheMap.values();
        CacheEntry[] records = values.toArray(new CacheEntry[values.size()]);
        Arrays.sort(records, LRU_COMPARATOR);
  
        for (int i = 0; i < records.length; i++) {
          if (cacheSize.get() <= targetSize) {
            break;           // we reclaimed everything we wanted to
          }
          CacheEntry c = records[i];
          evictCache(c.hdfsPath);
        }
      } finally {
        evictionInProgress = false; // eviction done.
      }
      if (LOG.isDebugEnabled()) {
        LOG.debug("Cache eviction complete. Current cache size is " +
                  cacheSize.get());
      }
    }
docs: Eviction occurs if the cache is full, we free up a specified
  percentage of the cache on every run. This method is synchronized
  so that only one thread is doing the eviction.