I think you do have a race condition. The test below should expose it. @Mock private MessageSource messageSource; @Test public void testExpiryDuringLoadingDoesNotInterfereWithGetMessageSourceCallInProgress() throws Exception { MessageSourceProvider sourceProvider = LoadingMessageSourceProvider.newBuilder().setExpiryTime(20, TimeUnit.MILLISECONDS) .setDefaultSource(messageSource).setLoader(new SlowLoader()) .build(); MessageSource messageSource = sourceProvider.getMessageSource(Locale.CHINA); assertThat(messageSource).isEqualTo(messageSource); } private class SlowLoader implements MessageSourceLoader { @Override public MessageSource load(Locale locale) { try { Thread.sleep(5000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } return messageSource; } } While I force the race condition to fail in the test by making the expiry time really short, and the loading time long, that is in itself not a necessary condition. Here's the code relevant snippet with added comments : synchronized (sources) { // cannot clean up here task = sources.get(locale); if (task == null || task.isCancelled()) { task = loadingTask(locale); sources.put(locale, task); service.execute(task); } } // yet here it can : task cancellation may happen during cleanup here // expiry may have been imminent just before the resource was requested try { final MessageSource source = task.get(timeoutDuration, timeoutUnit); // load may even be short : cancelation could have happened even before this request. return source == null ? defaultSource : source;