AsyncReloadableImpl extends AbstractReloadableImpl<T> { CompletableFuture<Void> refreshIfNotAlreadyRefreshing(final CompletableFuture<Void> old) { if (old == null || old.isDone()) { return CompletableFuture.runAsync(this::asyncReload); } else { logger.trace("Reload already in progress on {} with {}.", this, old); return old; } } AsyncReloadableImpl(final Supplier<T> supplier, final UnaryOperator<T> reloader,
            final Consumer<T> runWhenReloaded, final Set<ReloadListener<T>> listeners);  AsyncReloadableImpl(final Supplier<T> supplier, final UnaryOperator<T> reloader,
            final Consumer<T> runWhenReloaded, final Set<ReloadListener<T>> listeners,
            final Function<T, Duration> reloadAfter); @Override Either<Throwable, T> get(); @Override boolean hasValue();  }
@Test void performAsyncTest() { final AsyncReloadableImpl<String> r = (AsyncReloadableImpl<String>) Reloadable.with(() -> "") .async() .build(); final CompletableFuture<Void> first = r.refreshIfNotAlreadyRefreshing(null); assertThat(first).isNotNull(); first.completeExceptionally(new IllegalStateException()); final CompletableFuture<Void> second = r.refreshIfNotAlreadyRefreshing(first); assertThat(second).isNotNull() .isNotSameAs(first); final CompletableFuture<Void> third = mock(CompletableFuture.class); when(third.isDone()).thenReturn(false); assertThat(r.refreshIfNotAlreadyRefreshing(third)).isSameAs(third); }