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;
        }
    }