差異處
這裏顯示兩個版本的差異處。
Both sides previous revision 前次修改 下次修改 | 前次修改 | ||
java:java:java8:concurrent:blockingoperationwithcompletablefuture:avoid_transition_task [2019/01/13 14:29] tony [Problem] |
java:java:java8:concurrent:blockingoperationwithcompletablefuture:avoid_transition_task [2023/06/25 09:48] (目前版本) |
||
---|---|---|---|
行 1: | 行 1: | ||
+ | {{tag>java concurrency}} | ||
====== CompletableFuture - Avoid transition task from one thread to another. It costs. ====== | ====== CompletableFuture - Avoid transition task from one thread to another. It costs. ====== | ||
===== Problem ===== | ===== Problem ===== | ||
+ | 這問題通常發生在同時支援sync與async版本的API,或者是沒善用CompletableFuture功能的情況。以下是我的範例程式,基本上就是在透過CompletableFuture送出工作後,再等待執行結果以進行處理: | ||
<code java> | <code java> | ||
+ | public Response doSmth(){ | ||
+ | return doSmthAsync().join(); | ||
+ | } | ||
+ | |||
+ | public CompletableFuture<Response> doSmthAsync(){ | ||
+ | return CompletableFuture.supplyAsync(()->{ | ||
+ | return new Response(); | ||
+ | }); | ||
+ | } | ||
+ | |||
@Test | @Test | ||
public void transitionTask(){ | public void transitionTask(){ | ||
- | CompletableFuture<Response> asycRequest = | + | Response response = doSmth(); |
- | CompletableFuture.supplyAsync(()->{ | + | System.out.println(response); |
- | return new Response(); | + | |
- | }); | + | |
- | + | ||
- | Response reponse = asycRequest.join(); | + | |
- | System.out.println(reponse); | + | |
} | } | ||
</code> | </code> | ||
- | + | 這程式的執行過程如下圖所示:\\ | |
{{:java:java:java8:concurrent:blockingoperationwithcompletablefuture:java8_completablefuture_perf_block_client.png?450|}}\\ | {{:java:java:java8:concurrent:blockingoperationwithcompletablefuture:java8_completablefuture_perf_block_client.png?450|}}\\ | ||
- | + | 以單一工作來說,假如你的需求是屬於sync的情況,代表你必須等這個結果才能進行處理,那為何需要另外開一個thread pool來執行這個工作呢? 假如你的需求是要做成async的情況,那為何需要去等待結果去進行處理呢? 這兩者造成了client thread與使用的ExecutorServicec的浪費。\\ | |
(本篇圖片都來自於[[https://qconsf.com/sf2017/system/files/presentation-slides/cf.pdf|link]]) | (本篇圖片都來自於[[https://qconsf.com/sf2017/system/files/presentation-slides/cf.pdf|link]]) | ||
===== How to resolve? ===== | ===== How to resolve? ===== | ||
+ | 針對sync的情況,其實你根本不需要額外透過ExecutorService去執行,client thread就可以幫你完成這個任務。如果是針對async的情況,這時候應該要好好善用CompletableFuture的callback功能才對: | ||
+ | <code java> | ||
+ | @Test | ||
+ | public void fixTransitionTask(){ | ||
+ | doSmthAsync() | ||
+ | .thenAccept(response->{ | ||
+ | System.out.println(response); | ||
+ | }); | ||
+ | } | ||
+ | </code> | ||
+ | 這樣你的client thread就可以回去做它該做的事情,避免在那等待而浪費。 | ||
===== Reference ===== | ===== Reference ===== |