成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java 8原生API也可以開發(fā)響應(yīng)式代碼?

HtmlCssJs / 1440人閱讀

摘要:中使用了提供的原生接口對(duì)自身的異步化做了改進(jìn)??梢灾С趾蛢煞N調(diào)用方式。實(shí)戰(zhàn)通過(guò)下面的例子,可以看出的最大好處特性。

前段時(shí)間工作上比較忙,這篇文章一直沒來(lái)得及寫,本文是閱讀《Java8實(shí)戰(zhàn)》的時(shí)候,了解到Java 8里已經(jīng)提供了一個(gè)異步非阻塞的接口(CompletableFuture),可以實(shí)現(xiàn)簡(jiǎn)單的響應(yīng)式編程的模式,因此用這篇文章做個(gè)梳理。我是帶著下面這幾個(gè)問(wèn)題去學(xué)習(xí)CompletableFuture這個(gè)接口的,

CompletableFuture是為了解決什么問(wèn)題而設(shè)計(jì)的?

它的使用場(chǎng)景是什么?開源軟件中有實(shí)戰(zhàn)使用案例嗎?

CompletableFuture的常用API都有哪些?如何使用?

CompletableFuture和RxJava有什么不同?

這篇文章梳理下來(lái),基本上可以回答前面四個(gè)問(wèn)題,OK,我們進(jìn)入正文。

基本概念


RPC(遠(yuǎn)程方法調(diào)用)的四種方式有:oneway、sync、future和callback,在dubbo或bolt這類通信框架中,默認(rèn)使用的是sync模式(同步+阻塞),future和callback都屬于異步模式,不過(guò)future模式在get的時(shí)候會(huì)阻塞,callback模式則不需要等待結(jié)果,有結(jié)果后服務(wù)端會(huì)回調(diào)請(qǐng)求方。

異步調(diào)用這類模式,比較適合的場(chǎng)景是IO密集型場(chǎng)景,要執(zhí)行很多遠(yuǎn)程調(diào)用的任務(wù),并且這些調(diào)用耗時(shí)可能比較久。以openwrite中的一個(gè)case為例:我發(fā)布一篇文章,需要給幾個(gè)不同的寫作平臺(tái)創(chuàng)建文章,這時(shí)候我不希望這個(gè)過(guò)程是順序的,就比較適合用異步調(diào)用模式。

Future模式除了在get()調(diào)用的時(shí)候會(huì)阻塞外,還有其他的局限性,例如:沒有使用Java Lambda表達(dá)式的優(yōu)勢(shì),對(duì)一連串的異步調(diào)用可以支持,但是寫出來(lái)的代碼會(huì)比較復(fù)雜。

CompletableFuture的常用API

閱讀CompletableFuture的API的時(shí)候,我有一個(gè)體會(huì)——CompletableFuture之于Future,除了增加了回調(diào)這個(gè)最重要的特性,其他的特性有點(diǎn)像Stream對(duì)于集合迭代的增強(qiáng)。

使用CompletableFuture,我們可以像Stream一樣使用一部調(diào)用,可以處理一些級(jí)聯(lián)的異步調(diào)用(類似于Stream里的flatMap)、可以過(guò)濾一些無(wú)用的異步調(diào)用(anyOf、allOf)。

下面這張圖是我按照自己的理解,梳理除了CompletableFuture常見的API,閱讀的時(shí)候需要注意下面幾個(gè)點(diǎn):

把握幾個(gè)大的分類:創(chuàng)建CompletableFuture、獲取CompletableFuture的執(zhí)行結(jié)果、主動(dòng)結(jié)束CompletableFuture、異步調(diào)用任務(wù)的組合處理;

看著方法多,但是有規(guī)律可循,例如apply字樣的接口,傳入的方法參數(shù)都是有返回值的;

帶either字樣的,都是多個(gè)異步任務(wù)有一個(gè)滿足條件即可的;

帶executor方法的,都表示該方法可以用自定義的線程池來(lái)優(yōu)化性能。

Dubbo項(xiàng)目中的使用案例

Dubbo對(duì)于異步化的支持起始在2.6.x中就有提供,是在發(fā)布bean的時(shí)候加個(gè)屬性配置——async=true,然后利用上下文將異步標(biāo)識(shí)一層層傳遞下去。在之前的公司中有一次排查dubbo(當(dāng)時(shí)我們用的是dubbox)異步調(diào)用的問(wèn)題,最后查到的原因就是多個(gè)異步調(diào)用,上下文里的信息串了。

Dubbo 2.7 中使用了 JDK1.8 提供的 CompletableFuture 原生接口對(duì)自身的異步化做了改進(jìn)。CompletableFuture 可以支持 future 和 callback 兩種調(diào)用方式。在Dubbo最新的master代碼中,我知道了Dubbo的異步結(jié)果的定義,它的類圖如下,可以看出AsyncRpcResult是一個(gè)CompletableFuture接口的實(shí)現(xiàn)。

實(shí)戰(zhàn)Demo

通過(guò)下面的例子,可以看出CompletableFuture的最大好處——callback特性。首先定義一個(gè)接口,其中包括同步接口和該接口的異步版本。

public interface AsyncInterfaceExample {

    String computeSomeThine();

    CompletableFuture computeSomeThingAsync();
}

然后定義該接口的實(shí)現(xiàn)類,可以看出,如果要講現(xiàn)有的同步接口異步化,是比較容易的;

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 CompletableFuture computeSomeThingAsync() {
        return CompletableFuture.supplyAsync(this::computeSomeThine);
    }
}

然后看下我們的測(cè)試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 同步調(diào)用
        long start = System.currentTimeMillis();
        String someThing = asyncInterfaceExample.computeSomeThine();
        String other = getOtherThing();
        System.out.println("cost:" + (System.currentTimeMillis() - start) + "  result:" + someThing + other);

        //case2 異步調(diào)用,使用回調(diào)
        start = System.currentTimeMillis();
        CompletableFuture someThingFuture = 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();
            }
        });
    }
}

上面這個(gè)案例的執(zhí)行結(jié)果如下圖所示:
*
本號(hào)專注于后端技術(shù)、JVM問(wèn)題排查和優(yōu)化、Java面試題、個(gè)人成長(zhǎng)和自我管理等主題,為讀者提供一線開發(fā)者的工作和成長(zhǎng)經(jīng)驗(yàn),期待你能在這里有所收獲。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/76019.html

相關(guān)文章

  • Java8Java9 的主要新特性

    摘要:的主要新特性表達(dá)式允許把函數(shù)作為一個(gè)方法的參數(shù)傳遞進(jìn)方法中。作用解決被詬病的匿名內(nèi)部類的問(wèn)題。新特性模塊系統(tǒng)模塊是一個(gè)包的容器,最大的變化之一是引入模塊系統(tǒng)。支持標(biāo)準(zhǔn)標(biāo)準(zhǔn)是協(xié)議的最新版本,新的支持和流以及服務(wù)器推送特性。 Java 8 的主要新特性 1. Lambda 表達(dá)式 Lambda 允許把函數(shù)作為一個(gè)方法的參數(shù)傳遞進(jìn)方法中。 作用:解決 Java 被詬病的匿名內(nèi)部類的問(wèn)題。 2...

    SmallBoyO 評(píng)論0 收藏0
  • 關(guān)于云平臺(tái),開發(fā)者需要做哪些準(zhǔn)備?

    摘要:微軟已經(jīng)很久沒有支持開源社區(qū)了,這也是很多公司不采用的原因之一。當(dāng)然微軟總是致力于提供無(wú)的工具簡(jiǎn)單的語(yǔ)法和良好的教程,他們最近也意識(shí)到,開源可以為提供更多的創(chuàng)新和業(yè)務(wù)。 得益于CTO、CEO和CDO們積極的推動(dòng),IT基礎(chǔ)設(shè)施正在向云環(huán)境遷移,底層架構(gòu)師則在熱烈討論圍繞著云原生應(yīng)用的SaaS、PaaS和微服務(wù)架構(gòu),而開發(fā)者們正在大顯身手,努力探索云計(jì)算的魔盒,找出什么是對(duì)業(yè)務(wù)有價(jià)值的,什...

    newtrek 評(píng)論0 收藏0
  • Java編程方法論:響應(yīng)RxJava代碼設(shè)計(jì)實(shí)戰(zhàn)》序

    摘要:原文鏈接編程方法論響應(yīng)式與代碼設(shè)計(jì)實(shí)戰(zhàn)序,來(lái)自于微信公眾號(hào)次靈均閣正文內(nèi)容在一月的架構(gòu)和設(shè)計(jì)趨勢(shì)報(bào)告中,響應(yīng)式編程和函數(shù)式仍舊編列在第一季度的早期采納者中。 原文鏈接:《Java編程方法論:響應(yīng)式RxJava與代碼設(shè)計(jì)實(shí)戰(zhàn)》序,來(lái)自于微信公眾號(hào):次靈均閣 正文內(nèi)容 在《2019 一月的InfoQ 架構(gòu)和設(shè)計(jì)趨勢(shì)報(bào)告》1中,響應(yīng)式編程(Reactive Programming)和函數(shù)式...

    PAMPANG 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<