ConcurrentCachePopulator extends AbstractCachePopulator<K, V> { public void pupulate() { final List<CacheEntry<K, V>> entries = loadEntries(); if (entries.size() < concurrencyLevel) { concurrencyLevel = entries.size(); } final int partition = entries.size() / concurrencyLevel; for (int i = 0; i < concurrencyLevel; i++) { final int start = i * partition; final int stop = i != concurrencyLevel - 1 ? (i + 1) * partition : entries.size(); populatorExecutor.execute(() -> { for (int j = start; j < stop; j++) { cache.put(entries.get(j).getKey(), entries.get(j).getValue()); } }); } populatorExecutor.shutdown(); } ConcurrentCachePopulator(final Cache<K, V> cache, final int concurrencyLevel);  ConcurrentCachePopulator(Cache<K, V> cache); void pupulate();  }
@Test public void populate() { Object object = new Object(); List<CacheEntry<Object, Object>> entries = new ArrayList<CacheEntry<Object, Object>>(); entries.add(entry); doReturn(object).when(entry).getKey(); doReturn(object).when(entry).getValue(); doReturn(entries).when(populator).loadEntries(); doNothing().when(cache).put(object, object); populator.pupulate(); try { Thread.sleep(100); } catch (InterruptedException e) { } verify(cache, atLeast(1)).put(object, object); verify(populator).loadEntries(); }