這是本文件的舊版!


CompletableFuture - It may be useful to build chain of actions before execution.

下方這隻程式在Java8中應是相當常見:

CompletableFuture.supplyAsync(()->{
	dumpCurrentThreadName("supplyAsync");
	return new Response();
}).whenComplete((response, ex)->{
	dumpCurrentThreadName("whenComplete");
	// process response
});
它的問題是如果supplyAsync中的工作,在執行whenComplete前就結束了;當執行whenComplete時,有可能會使用client thread去執行工作而影響到工作接收的速度。以下是我的執行結果:
ForkJoinPool.commonPool-worker-3: supplyAsync
main: whenComplete
假如你的callback chain很長,遇到這個情況的機率就會越高。

面對這個問題,在Java9中,允許你將實際的執行工作放到callback chain之後:

CompletableFuture<Response> asyncJob = new CompletableFuture<>();
 
asyncJob.whenComplete((response, ex)->{
	dumpCurrentThreadName("whenComplete");
});
 
asyncJob.completeAsync(()->{
	dumpCurrentThreadName("supplyAsync");
	return new Response();
});
輸出結果如下:
ForkJoinPool.commonPool-worker-3: supplyAsync
ForkJoinPool.commonPool-worker-3: whenComplete
這樣可以避免client thread跑去執行原本預期要async的工作,而增加了client thread的回應速度。

至於Java8目前我使用下面方式來達到lazy launch:
CompletableFuture<Response> asyncJob = new CompletableFuture<>();
job.thenApply((ret)->{
	dumpCurrentThreadName("supplyAsync");
	return new Response();rrentThreadName("runAsync");
 
}).whenComplete((response, ex)->{
	dumpCurrentThreadName("whenComplete");
});
 
CompletableFuture.runAsync(()->{
	asyncJob.complete(null);
})