@Test
    void testRebuildConcurrency() throws ExecutionException, InterruptedException {
        final int coreCount = Runtime.getRuntime().availableProcessors();
        LOGGER.info("coreCount: {}", coreCount);
        final ExecutorService executorService = Executors.newFixedThreadPool(coreCount);
        final int iterations = 500;

        final LongAdder counter = new LongAdder();

        final Function<Integer, String> valueProvider = monthNo -> {
            counter.increment();
            return numberToMonth(monthNo);
        };

        final CountDownLatch countDownLatch = new CountDownLatch(coreCount);

        for (int i = 0; i < coreCount; i++) {
            final long seed = i;
            CompletableFuture.runAsync(() -> {
                LOGGER.info("Reader thread starting");
                final Random random = new Random(seed);
                for (int j = 0; j < iterations; j++) {

                    final int monthNo = random.nextInt(ALL_MONTHS_COUNT) + 1;

                    final String name = cache.get(monthNo, valueProvider);

                    assertThat(name)
                            .isEqualTo(numberToMonth(monthNo));
                    ThreadUtil.sleepIgnoringInterrupts(random.nextInt(5));
                }
                countDownLatch.countDown();
                LOGGER.info("Reader thread finishing");
            }, executorService);
        }

        final Random random = new Random();

        CompletableFuture.runAsync(() -> {
            LOGGER.info("Re-builder thread starting");
            while (countDownLatch.getCount() > 0) {
                LOGGER.info("Rebuilding");
                cache.rebuild();
                ThreadUtil.sleepIgnoringInterrupts(random.nextInt(50) + 100);
            }
            LOGGER.info("Re-builder thread finishing");
        }).get();

        LOGGER.info("valueProvider call count: {}", counter.sum());
    }
Make sure that many threads can keep hitting the cache while another thread
periodically rebuilds it.
stroom-cache/stroom-cache-impl/src/test/java/stroom/cache/impl/TestStroomCacheImpl.java