Это не имеет ничего общего с UUID, за исключением того, что его генерация занимает некоторое время, и вы не ожидаете завершения.
Поскольку все операции выполняются в фоновых потоках, а вы возвращаетесь из *При использовании метода 1003 * JVM определит, что поток, не являющийся демоном, больше не работает, и завершит работу.
Просто добавьте операцию ожидания завершения:
final Supplier<User> makeUserSupplier = () -> makeUser();
final Supplier<String> uuidSupplier = () -> makeUUID();
final CompletableFuture<User> futureUser = CompletableFuture.supplyAsync(makeUserSupplier);
final CompletableFuture<String> futureUUID = CompletableFuture.supplyAsync(uuidSupplier);
CompletableFuture.allOf(futureUser, futureUUID)
.thenApplyAsync(aVoid -> {
final User user = futureUser.join();
final String uuid = futureUUID.join();
return "received user + " + user + " and uuid is " + uuid ;
})
.handle((ok, e) -> {
System.out.println("ok----" + ok);
System.out.println("e----" + e);
return null;
})
.join(); // wait for completion
Обратите внимание, что в исходном файлекод, вы использовали .allOf(futureUser, futureUser)
вместо .allOf(futureUser, futureUUID)
, поэтому цепная операция может выполняться, когда futureUUID
еще не завершена, что может привести к блокировке рабочего потока в вызове futureUUID.join()
.
Ваш код был бы намного проще, если бы вы использовали
final CompletableFuture<User> futureUser = CompletableFuture.supplyAsync(() -> makeUser());
final CompletableFuture<String> futureUUID = CompletableFuture.supplyAsync(() -> makeUUID());
futureUser.thenCombineAsync(futureUUID, (user, uuid) -> {
return "received user + " + user + " and uuid is " + uuid;
})
.handle((ok, e) -> {
System.out.println("ok----" + ok);
System.out.println("e----" + e);
return null;
})
.join(); // wait for completion
, который также неуязвим для ошибки, допущенной с allOf
, поскольку в рабочем потоке не требуется вызов join()
.