@Test
  public void testCacheEvictionThreadSafe() throws Exception {
    long maxSize = 100000;
    int numBlocks = 9;
    int testRuns = 10;
    final long blockSize = calculateBlockSizeDefault(maxSize, numBlocks);
    assertTrue("calculateBlockSize appears broken.", blockSize * numBlocks <= maxSize);

    final LruAdaptiveBlockCache cache = new LruAdaptiveBlockCache(maxSize, blockSize);
    EvictionThread evictionThread = cache.getEvictionThread();
    assertNotNull(evictionThread);
    Waiter.waitFor(CONF, 10000, 100, () -> evictionThread.isEnteringRun());
    final String hfileName = "hfile";
    int threads = 10;
    final int blocksPerThread = 5 * numBlocks;
    for (int run = 0; run != testRuns; ++run) {
      final AtomicInteger blockCount = new AtomicInteger(0);
      ExecutorService service = Executors.newFixedThreadPool(threads);
      for (int i = 0; i != threads; ++i) {
        service.execute(() -> {
          for (int blockIndex = 0; blockIndex < blocksPerThread
            || (!cache.isEvictionInProgress()); ++blockIndex) {
            CachedItem block =
              new CachedItem(hfileName, (int) blockSize, blockCount.getAndIncrement());
            boolean inMemory = Math.random() > 0.5;
            cache.cacheBlock(block.cacheKey, block, inMemory);
          }
          cache.evictBlocksByHfileName(hfileName);
        });
      }
      service.shutdown();
      // The test may fail here if the evict thread frees the blocks too fast
      service.awaitTermination(10, TimeUnit.MINUTES);
      Waiter.waitFor(CONF, 10000, 100, new ExplainingPredicate<Exception>() {
        @Override
        public boolean evaluate() throws Exception {
          return cache.getBlockCount() == 0;
        }

        @Override
        public String explainFailure() throws Exception {
          return "Cache block count failed to return to 0";
        }
      });
      assertEquals(0, cache.getBlockCount());
      assertEquals(cache.getOverhead(), cache.getCurrentSize());
    }
  }
Tests the concurrent LruAdaptiveBlockCache.
<p>
Tests will ensure it grows and shrinks in size properly, evictions run when they're supposed to
and do what they should, and that cached blocks are accessible when expected to be.
hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/TestLruAdaptiveBlockCache.java