Это потому, что ваш futures
никогда не будет завершен. CompletableFuture.allOf
возвращает новое CompletableFuture, которое завершается, когда все заданные CompletableFutures
завершены.
future1.complete()
, future2.complete()
и future3.complete()
никогда не будут вызваны.
CompletableFuture.join()
возвращает результат, если будущее завершено. Поскольку вы высмеиваете фьючерсы в своем коде, они возвращают строки, определенные в expectedResults
для join
, даже если они не завершены. Но это именно проблема. Они не завершены. Вот почему тест не заканчивается sh.
Я немного скорректировал ваш тестовый класс, чтобы продемонстрировать, как он работает:
public class FutureTest {
@Test
public void testSequence1() {
List<CompletableFuture<String>> futures = getFutures();
CompletableFuture<Void> myCombinedFuture = sequence(futures);
// here we complete each future
futures.forEach(future -> future.complete("future-completed"));
myCombinedFuture.join();
// this works because we completed all futures before
Assert.assertTrue(myCombinedFuture.isDone());
}
@Test
public void testSequence2() {
List<CompletableFuture<String>> futures = getFutures();
CompletableFuture<Void> myCombinedFuture = sequence(futures);
futures.get(0).complete("completed-future1");
futures.get(1).complete("completed-future2");
myCombinedFuture.join();
// this does not work because future3 is not completed -> we wait forever
Assert.assertTrue(myCombinedFuture.isDone());
}
@Test
public void testSequence3() {
List<CompletableFuture<String>> futures = getFutures();
CompletableFuture<Void> myCombinedFuture = sequence(futures);
futures.get(0).complete("completed-future1");
futures.get(1).complete("completed-future2");
// complete future 3 asynchronous after 2 seconds
futures.get(2).completeAsync(() -> {
// wait for 2 seconds
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "completed-future3";
});
myCombinedFuture.join();
// after 2 seconds all futures are completed and the test will pass
Assert.assertTrue(myCombinedFuture.isDone());
}
public CompletableFuture<Void> sequence(
List<CompletableFuture<String>> futuresList) {
return CompletableFuture.allOf(
futuresList.toArray(new CompletableFuture[0]));
}
public List<CompletableFuture<String>> getFutures() {
return List.of(
new CompletableFuture<>(),
new CompletableFuture<>(),
new CompletableFuture<>()
);
}
}