摘要:中使用了提供的原生接口對自身的異步化做了改進。可以支持和兩種調用方式。實戰通過下面的例子,可以看出的最大好處特性。
前段時間工作上比較忙,這篇文章一直沒來得及寫,本文是閱讀《Java8實戰》的時候,了解到Java 8里已經提供了一個異步非阻塞的接口(CompletableFuture),可以實現簡單的響應式編程的模式,因此用這篇文章做個梳理。我是帶著下面這幾個問題去學習CompletableFuture這個接口的,
CompletableFuture是為了解決什么問題而設計的?
它的使用場景是什么?開源軟件中有實戰使用案例嗎?
CompletableFuture的常用API都有哪些?如何使用?
CompletableFuture和RxJava有什么不同?
這篇文章梳理下來,基本上可以回答前面四個問題,OK,我們進入正文。
基本概念
RPC(遠程方法調用)的四種方式有:oneway、sync、future和callback,在dubbo或bolt這類通信框架中,默認使用的是sync模式(同步+阻塞),future和callback都屬于異步模式,不過future模式在get的時候會阻塞,callback模式則不需要等待結果,有結果后服務端會回調請求方。
異步調用這類模式,比較適合的場景是IO密集型場景,要執行很多遠程調用的任務,并且這些調用耗時可能比較久。以openwrite中的一個case為例:我發布一篇文章,需要給幾個不同的寫作平臺創建文章,這時候我不希望這個過程是順序的,就比較適合用異步調用模式。
Future模式除了在get()調用的時候會阻塞外,還有其他的局限性,例如:沒有使用Java Lambda表達式的優勢,對一連串的異步調用可以支持,但是寫出來的代碼會比較復雜。
CompletableFuture的常用API閱讀CompletableFuture的API的時候,我有一個體會——CompletableFuture之于Future,除了增加了回調這個最重要的特性,其他的特性有點像Stream對于集合迭代的增強。
使用CompletableFuture,我們可以像Stream一樣使用一部調用,可以處理一些級聯的異步調用(類似于Stream里的flatMap)、可以過濾一些無用的異步調用(anyOf、allOf)。
下面這張圖是我按照自己的理解,梳理除了CompletableFuture常見的API,閱讀的時候需要注意下面幾個點:
把握幾個大的分類:創建CompletableFuture、獲取CompletableFuture的執行結果、主動結束CompletableFuture、異步調用任務的組合處理;
看著方法多,但是有規律可循,例如apply字樣的接口,傳入的方法參數都是有返回值的;
帶either字樣的,都是多個異步任務有一個滿足條件即可的;
帶executor方法的,都表示該方法可以用自定義的線程池來優化性能。
Dubbo項目中的使用案例Dubbo對于異步化的支持起始在2.6.x中就有提供,是在發布bean的時候加個屬性配置——async=true,然后利用上下文將異步標識一層層傳遞下去。在之前的公司中有一次排查dubbo(當時我們用的是dubbox)異步調用的問題,最后查到的原因就是多個異步調用,上下文里的信息串了。
Dubbo 2.7 中使用了 JDK1.8 提供的 CompletableFuture 原生接口對自身的異步化做了改進。CompletableFuture 可以支持 future 和 callback 兩種調用方式。在Dubbo最新的master代碼中,我知道了Dubbo的異步結果的定義,它的類圖如下,可以看出AsyncRpcResult是一個CompletableFuture接口的實現。
實戰Demo通過下面的例子,可以看出CompletableFuture的最大好處——callback特性。首先定義一個接口,其中包括同步接口和該接口的異步版本。
public interface AsyncInterfaceExample { String computeSomeThine(); CompletableFuturecomputeSomeThingAsync(); }
然后定義該接口的實現類,可以看出,如果要講現有的同步接口異步化,是比較容易的;
public class AsyncInterfaceExampleImpl implements AsyncInterfaceExample { @Override public String computeSomeThine() { try { Thread.sleep(2000); } catch (InterruptedException e) { throw new RuntimeException(e); } return "hello, world"; } @Override public CompletableFuturecomputeSomeThingAsync() { return CompletableFuture.supplyAsync(this::computeSomeThine); } }
然后看下我們的測試case,如下:
public class AsyncInterfaceExampleTest { private static String getOtherThing() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } return "other"; } public static void main(String[] args) { AsyncInterfaceExample asyncInterfaceExample = new AsyncInterfaceExampleImpl(); //case1 同步調用 long start = System.currentTimeMillis(); String someThing = asyncInterfaceExample.computeSomeThine(); String other = getOtherThing(); System.out.println("cost:" + (System.currentTimeMillis() - start) + " result:" + someThing + other); //case2 異步調用,使用回調 start = System.currentTimeMillis(); CompletableFuturesomeThingFuture = asyncInterfaceExample.computeSomeThingAsync(); other = getOtherThing(); long finalStart = start; String finalOther = other; someThingFuture.whenComplete((returnValue, exception) -> { if (exception == null) { System.out.println( "cost:" + (System.currentTimeMillis() - finalStart) + " result:" + returnValue + finalOther); } else { exception.printStackTrace(); } }); } }
上面這個案例的執行結果如下圖所示:
*
本號專注于后端技術、JVM問題排查和優化、Java面試題、個人成長和自我管理等主題,為讀者提供一線開發者的工作和成長經驗,期待你能在這里有所收獲。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/76019.html
摘要:的主要新特性表達式允許把函數作為一個方法的參數傳遞進方法中。作用解決被詬病的匿名內部類的問題。新特性模塊系統模塊是一個包的容器,最大的變化之一是引入模塊系統。支持標準標準是協議的最新版本,新的支持和流以及服務器推送特性。 Java 8 的主要新特性 1. Lambda 表達式 Lambda 允許把函數作為一個方法的參數傳遞進方法中。 作用:解決 Java 被詬病的匿名內部類的問題。 2...
摘要:微軟已經很久沒有支持開源社區了,這也是很多公司不采用的原因之一。當然微軟總是致力于提供無的工具簡單的語法和良好的教程,他們最近也意識到,開源可以為提供更多的創新和業務。 得益于CTO、CEO和CDO們積極的推動,IT基礎設施正在向云環境遷移,底層架構師則在熱烈討論圍繞著云原生應用的SaaS、PaaS和微服務架構,而開發者們正在大顯身手,努力探索云計算的魔盒,找出什么是對業務有價值的,什...
摘要:原文鏈接編程方法論響應式與代碼設計實戰序,來自于微信公眾號次靈均閣正文內容在一月的架構和設計趨勢報告中,響應式編程和函數式仍舊編列在第一季度的早期采納者中。 原文鏈接:《Java編程方法論:響應式RxJava與代碼設計實戰》序,來自于微信公眾號:次靈均閣 正文內容 在《2019 一月的InfoQ 架構和設計趨勢報告》1中,響應式編程(Reactive Programming)和函數式...
閱讀 3164·2021-11-19 09:40
閱讀 3653·2021-11-16 11:52
閱讀 2984·2021-11-11 16:55
閱讀 3174·2019-08-30 15:55
閱讀 1182·2019-08-30 13:08
閱讀 1659·2019-08-29 17:03
閱讀 3016·2019-08-29 16:19
閱讀 2583·2019-08-29 13:43