ConcurrentEvictionListener extends QueuingEvictionListener<K, V> { protected void init(int queueSize, int concurrencyLevel) { cacheTasks = new ArrayBlockingQueue<>(queueSize); final ExecutorService drainerService = Executors.newFixedThreadPool(concurrencyLevel, runnable -> ThreadUtils .createDaemonThread(runnable, "imcache:concurrentAsyncEvictionDrainer(thread=" + NO_OF_EVICTION_DRAINERS.incrementAndGet() + ")")); for (int i = 0; i < concurrencyLevel; i++) { drainerService.execute(() -> { while (true) { drainQueue(); } }); } } ConcurrentEvictionListener();  ConcurrentEvictionListener(final int batchSize, final int queueSize,
      final int concurrencyLevel);  static final int DEFAULT_CONCURRENCY_LEVEL; }
@Test public void init() throws InterruptedException { doNothing().when(asyncEvictionListener).drainQueue(); asyncEvictionListener.init(1000, 3); Thread.sleep(5); verify(asyncEvictionListener, atLeast(1)).drainQueue(); }