這是本文件的舊版!


CompletableFuture - Carefully avoid transition task from one thread to another. It costs.

這個問題我使用以下範例來說明:

private ExecutorService es = Executors.newFixedThreadPool(2);
@Test
public void transitionTaskOfCallback(){
	CompletableFuture.supplyAsync(()->{
		return new Response();
	}, es)
	.thenAcceptAsync(response->{
		System.out.println(response);
	}, es);
}
這段程式透過supplyAsync將工作送給es去執行,當執行完畢後,會再透過thenAcceptAsync把後續處理交給es執行;或許你的程式執行起來,可以很順利地拿到你要的結果,但這裡做了白工。

由於這兩段都使用了async的方式,也都是把工作交由es去執行。假如es中有多個thread,這可能會造成額外的thread context switch;因為第一個工作與第二個工作並不一定會在同一個thread上執行。

首先你必須要搞清楚,你到底在做什麼.. 假如你是很單純的在supplyAsync中做些計算,然後callback是要針對計算結果做處理,那幹嘛需要多此一舉把它宣告成async的寫法呢? 只要改成以下寫法,就可以讓你維持原本的Thread繼續執行:

@Test
public void fixTransitionTaskOfCallback(){
	CompletableFuture.supplyAsync(()->{
		return new Response();
	}, es)
	.thenAccept(response->{
		System.out.println(response);
	});
}