UUID.randomUUID() 的 CompletableFuture 问题
CompletableFuture issue with UUID.randomUUID()
所以我决定开始使用 Java8 中的 CompletableFuture
,但我无法弄清楚这段代码有什么问题:
public static void main(String...strings) throws Exception {
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;
});
}
private static User makeUser() throws RuntimeException {
// throw new RuntimeException("lkj");
return new User(1L, "mm", "ll", "kk");
}
private static String makeUUID() throws RuntimeException {
return UUID.randomUUID().toString();
// return "dummy";
}
其中 User
class 定义为:
@Data
@AllArgsConstructor
public class User {
private Long id;
private String username;
private String password;
private String role;
}
我得到的行为是:
- 当我使用
UUID.randomUUID().toString()
时,我的控制台没有打印任何内容,而当我使用一些随机 String
. 时,我得到了结果
- 调试时我能到达的最后一个断点是我加入 futureUUID
final String uuid = futureUUID.join();
的那一行,然后我的程序停止了,没有结果。
有人可以尝试向我解释为什么我在使用 UUID 时会出现这种奇怪的行为吗?
PS: 刚开始学习CompletableFuture
想着parallel Futures,无意间就想到了这个
此致。
这与 UUID 无关,只是它的生成需要一些时间并且您不需要等待完成。
由于所有操作都发生在后台线程中,并且您从 main
方法返回,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()
调用。
所以我决定开始使用 Java8 中的 CompletableFuture
,但我无法弄清楚这段代码有什么问题:
public static void main(String...strings) throws Exception {
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;
});
}
private static User makeUser() throws RuntimeException {
// throw new RuntimeException("lkj");
return new User(1L, "mm", "ll", "kk");
}
private static String makeUUID() throws RuntimeException {
return UUID.randomUUID().toString();
// return "dummy";
}
其中 User
class 定义为:
@Data
@AllArgsConstructor
public class User {
private Long id;
private String username;
private String password;
private String role;
}
我得到的行为是:
- 当我使用
UUID.randomUUID().toString()
时,我的控制台没有打印任何内容,而当我使用一些随机String
. 时,我得到了结果
- 调试时我能到达的最后一个断点是我加入 futureUUID
final String uuid = futureUUID.join();
的那一行,然后我的程序停止了,没有结果。
有人可以尝试向我解释为什么我在使用 UUID 时会出现这种奇怪的行为吗?
PS: 刚开始学习CompletableFuture
想着parallel Futures,无意间就想到了这个
此致。
这与 UUID 无关,只是它的生成需要一些时间并且您不需要等待完成。
由于所有操作都发生在后台线程中,并且您从 main
方法返回,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()
调用。