我是 Java 程序员,但我也知道 JS 里面有个Promise,感觉Promise的语法比 Java 的CompletableFuture这套 API 优雅很多。Promise总共也需要知道then,catch两种语句,而CompletableFuture则各种方法都有十几二十个了。
还有些匪夷所思的行为,比如下面这个:
同步编排(无 Async 后缀)的方法,例如
thenCompose不会把任务重新提交给线程池排队,而是尽量复用现有的线程。具体用哪个线程,取决于代码运行时的时机
情况 A (前置任务还没执行完): 当你调用 thenCompose 时,如果前置任务还在跑,那么 thenCompose 里的代码会在前置任务所在的线程中接着运行。
情况 B (前置任务已经执行完了): 当你调用 thenCompose 时,如果前置任务早就跑完了,那么 thenCompose 里的代码会在当前调用代码的主线程( Caller Thread )中立刻运行。
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
// 假设在 ForkJoinPool-1 线程执行
return "Hello";
});
// 因为没有 Async ,它会尝试复用线程
future1.thenCompose(result -> {
// 如果 future1 刚执行完,这里大概率还是在 ForkJoinPool-1 线程执行
// 如果 future1 早就执行完了,这里会在 Main 线程执行
return CompletableFuture.supplyAsync(() -> result + " World");
});
那程序员调这个方法的时候,相当于遇到不确定性行为(nondeterministic behavior)了。我都不知道我要调的方法到底是在哪个线程执行,会不会把当前线程卡住