最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

說說Java異步調(diào)用的幾種方式

 更新時(shí)間:2021年08月03日 08:44:16   作者:Acelin_H  
本文主要介紹了說說Java異步調(diào)用的幾種方式,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

日常開發(fā)中,會(huì)經(jīng)常遇到說,前臺(tái)調(diào)服務(wù),然后觸發(fā)一個(gè)比較耗時(shí)的異步服務(wù),且不用等異步任務(wù)的處理結(jié)果就對(duì)原服務(wù)進(jìn)行返回。這里就涉及的Java異步調(diào)用的一個(gè)知識(shí)。下面本文嘗試將Java異步調(diào)用的多種方式進(jìn)行歸納。

一、通過創(chuàng)建新線程

首先的我們得認(rèn)識(shí)到,異步調(diào)用的本質(zhì),其實(shí)是通過開啟一個(gè)新的線程來執(zhí)行。如以下例子:

public static void main(String[] args) throws Exception{

    System.out.println("主線程 =====> 開始 =====> " + System.currentTimeMillis());

    new Thread(() -> {
        System.out.println("異步線程 =====> 開始 =====> " + System.currentTimeMillis());
        try{
            Thread.sleep(5000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println("異步線程 =====> 結(jié)束 =====> " + System.currentTimeMillis());
    }).start();

    Thread.sleep(2000);

    System.out.println("主線程 =====> 結(jié)束 =====> " + System.currentTimeMillis());
    
}

數(shù)據(jù)結(jié)果如下所示,我們知道,System.currentTimeMillis()時(shí)間單位為ms。

主線程 =====> 開始 =====> 1627893837146
異步線程 =====> 開始 =====> 1627893837200
主線程 =====> 結(jié)束 =====> 1627893839205
異步線程 =====> 結(jié)束 =====> 1627893842212

我們通過線程休眠來達(dá)成主線程執(zhí)行時(shí)間2秒左右,異步線程執(zhí)行5秒左右的效果。通過打印出來的時(shí)間戳倒數(shù)第四位(秒位)我們可以看出,兩個(gè)的線程執(zhí)行總時(shí)間為5秒左右,符合異步執(zhí)行的特征

以上是采用Runable實(shí)現(xiàn)多線程創(chuàng)建方式的lambda寫法,關(guān)于的lambda知識(shí),可參考Java Lambda 表達(dá)式;而關(guān)于多線程的多種實(shí)現(xiàn)方式,Java多線程事務(wù)管理一文有提及,可移步查看

二、通過線程池

因?yàn)楫惒饺蝿?wù)的實(shí)現(xiàn)本質(zhì)的由新線程來執(zhí)行任務(wù),所以通過線程池的也可以實(shí)現(xiàn)異步執(zhí)行。寫法同我們利用線程池開啟多線程一樣。但由于我們的目的不是執(zhí)行多線程,而是異步執(zhí)行任務(wù),所以一般需要另外一個(gè)線程就夠了。

因此區(qū)別于執(zhí)行多線程任務(wù)的我們常用的newFixedThreadPool,在執(zhí)行異步任務(wù)時(shí),我們用newSingleThreadExecutor 來創(chuàng)建一個(gè)單個(gè)線程的線程池。

public static void main(String[] args) throws Exception{

    System.out.println("主線程 =====> 開始 =====> " + System.currentTimeMillis());

    ExecutorService executorService = Executors.newSingleThreadExecutor();
    executorService.submit(()->{
        System.out.println("異步線程 =====> 開始 =====> " + System.currentTimeMillis());
        try{
            Thread.sleep(5000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println("異步線程 =====> 結(jié)束 =====> " + System.currentTimeMillis());
    });
    executorService.shutdown(); // 回收線程池

    Thread.sleep(2000);

    System.out.println("主線程 =====> 結(jié)束 =====> " + System.currentTimeMillis());
    
}

執(zhí)行結(jié)果如下:

主線程 =====> 開始 =====> 1627895467578
異步線程 =====> 開始 =====> 1627895467635
主線程 =====> 結(jié)束 =====> 1627895469644
異步線程 =====> 結(jié)束 =====> 1627895472649

可以看到,結(jié)果跟第一種結(jié)果是基本一致的。

溫馨提示:不要忘記線程池的回收

三、通過@Async注解

我們都知道,SpringBoot項(xiàng)目有一個(gè)的很重要的特點(diǎn)就是的注解化。如果你的項(xiàng)目是SpringBoot,那就又多了一種選擇——@Async注解。

使用起來也非常簡(jiǎn)單,將要異步執(zhí)行的代碼封裝成一個(gè)方法,然后用@Async注解該方法,然后在主方法中直接調(diào)用就行。

@Test
public void mainThread() throws Exception{

    System.out.println("主線程 =====> 開始 =====> " + System.currentTimeMillis());
    collectionBill.asyncThread();
    Thread.sleep(2000);
    System.out.println("主線程 =====> 結(jié)束 =====> " + System.currentTimeMillis());

    Thread.sleep(4000); // 用于防止jvm停止,導(dǎo)致異步線程中斷
}
@Async
public void asyncThread(){
    System.out.println("異步線程 =====> 開始 =====> " + System.currentTimeMillis());
    try{
        Thread.sleep(5000);
    }catch (InterruptedException e){
        e.printStackTrace();
    }
    System.out.println("異步線程 =====> 結(jié)束 =====> " + System.currentTimeMillis());
}

執(zhí)行結(jié)果如下:

主線程 =====> 開始 =====> 1627897539948
異步線程 =====> 開始 =====> 1627897539956
主線程 =====> 結(jié)束 =====> 1627897541965
異步線程 =====> 結(jié)束 =====> 1627897544966

有以下兩點(diǎn)需要注意:

類似@Tranctional注解,@Async注解的方法與調(diào)用方法不能在同一個(gè)類中,否則不生效
JUnit框架的設(shè)計(jì)不考慮多線程場(chǎng)景,所以主線程退出后,子線程也會(huì)跟著立即退出,所以可以在后面加多線程休眠時(shí)間來觀察異步線程的執(zhí)行情況

四、通過CompletableFuture

CompletableFuture是JDK1.8的新特性,是對(duì)Future的擴(kuò)展。CompletableFuture實(shí)現(xiàn)了CompletionStage接口和Future接口,增加了異步回調(diào)、流式處理、多個(gè)Future組合處理的能力。

實(shí)現(xiàn)代碼如下:

public static void main(String[] args) throws Exception{

    System.out.println("主線程 =====> 開始 =====> " + System.currentTimeMillis());

    ExecutorService executorService = Executors.newSingleThreadExecutor();
    CompletableFuture.runAsync(() ->{
        System.out.println("異步線程 =====> 開始 =====> " + System.currentTimeMillis());
        try{
            Thread.sleep(5000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println("異步線程 =====> 結(jié)束 =====> " + System.currentTimeMillis());
    },executorService);
    executorService.shutdown(); // 回收線程池

    Thread.sleep(2000);

    System.out.println("主線程 =====> 結(jié)束 =====> " + System.currentTimeMillis());
    
}

同樣可以實(shí)現(xiàn)類似的結(jié)果如下:

主線程 =====> 開始 =====> 1627898354914
異步線程 =====> 開始 =====> 1627898354977
主線程 =====> 結(jié)束 =====> 1627898356980
異步線程 =====> 結(jié)束 =====> 1627898359979

CompletableFuture有者非常強(qiáng)大的功能,能給我們帶來非常絲滑的編程體驗(yàn)。后續(xù)會(huì)寫一篇文章來詳細(xì)介紹CompletableFuture

到此這篇關(guān)于說說Java異步調(diào)用的幾種方式的文章就介紹到這了,更多相關(guān)Java異步調(diào)用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中Comparator升序降序的具體使用

    Java中Comparator升序降序的具體使用

    本文主要介紹了Java中Comparator升序降序的具體使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Springboot基礎(chǔ)之RedisUtils工具類

    Springboot基礎(chǔ)之RedisUtils工具類

    本文來說下RedisUtils工具類,主要介紹了整合Redis、MyBatis,封裝RedisUtils工具類等知識(shí),文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有很好的幫助,需要的朋友可以參考下
    2021-05-05
  • Spring自定義注解的實(shí)現(xiàn)與使用方式

    Spring自定義注解的實(shí)現(xiàn)與使用方式

    注解是Java中用于類、方法、參數(shù)、包的裝飾標(biāo)志,本身不具備功能,但可定義參數(shù),Java包含內(nèi)建注解和元注解,如@Target、@Retention等,描述注解的使用范圍和生命周期,Spring的AOP(面向切面編程)可以結(jié)合注解實(shí)現(xiàn)功能,如權(quán)限控制和日志記錄
    2024-09-09
  • 詳解Java動(dòng)態(tài)加載數(shù)據(jù)庫驅(qū)動(dòng)

    詳解Java動(dòng)態(tài)加載數(shù)據(jù)庫驅(qū)動(dòng)

    本篇文章主要介紹了詳解Java動(dòng)態(tài)加載數(shù)據(jù)庫驅(qū)動(dòng),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-05-05
  • Java實(shí)現(xiàn)Excel導(dǎo)入導(dǎo)出的步驟詳解

    Java實(shí)現(xiàn)Excel導(dǎo)入導(dǎo)出的步驟詳解

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)Excel的導(dǎo)入、導(dǎo)出,文中示例代碼介紹的非常詳細(xì),對(duì)我們的學(xué)習(xí)或工作有一定的幫助,感興趣的小伙伴們可以參考一下
    2023-06-06
  • 使用迭代器模式來進(jìn)行Java的設(shè)計(jì)模式編程

    使用迭代器模式來進(jìn)行Java的設(shè)計(jì)模式編程

    這篇文章主要介紹了使用迭代器模式來進(jìn)行Java的設(shè)計(jì)模式編程,文中對(duì)迭代器模式中的容器封裝方面的知識(shí)進(jìn)行了講解,需要的朋友可以參考下
    2016-02-02
  • SpringBoot傳遞單一參數(shù)時(shí)@RequestParam和@RequestBody的區(qū)別小結(jié)

    SpringBoot傳遞單一參數(shù)時(shí)@RequestParam和@RequestBody的區(qū)別小結(jié)

    用SpringBoot框架做項(xiàng)目時(shí),經(jīng)常需要前端給后端傳遞參數(shù),本文主要介紹了SpringBoot傳遞單一參數(shù)時(shí)@RequestParam和@RequestBody的區(qū)別,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-08-08
  • Spring Boot詳解配置文件的用途與用法

    Spring Boot詳解配置文件的用途與用法

    SpringBoot項(xiàng)目是一個(gè)標(biāo)準(zhǔn)的Maven項(xiàng)目,它的配置文件需要放在src/main/resources/下,其文件名必須為application,其存在兩種文件形式,分別是properties和yaml(或者yml)文件
    2022-06-06
  • IDEA 工程里 new不出來Vue文件的圖文解決方案

    IDEA 工程里 new不出來Vue文件的圖文解決方案

    這篇文章主要介紹了IDEA 工程里 new不出來Vue文件的解決方案,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • MyBatis框架零基礎(chǔ)快速入門案例詳解

    MyBatis框架零基礎(chǔ)快速入門案例詳解

    MyBatis本是apache的一個(gè)開源項(xiàng)目iBatis,2010年這個(gè)項(xiàng)目由apache?software?foundation遷移到了google?code,并且改名為MyBatis。2013年11月遷移到Github。iBATIS一詞來源于“internet”和“abatis”的組合,是一個(gè)基于Java的持久層框架
    2022-04-04

最新評(píng)論

山丹县| 东山县| 郑州市| 昌都县| 上饶县| 城市| 庆元县| 岑溪市| 乌什县| 诏安县| 应城市| 长沙市| 泽库县| 伊宁县| 桑日县| 精河县| 道孚县| 南木林县| 宜兰市| 开化县| 明溪县| 哈尔滨市| 神农架林区| 江安县| 黔江区| 蒲城县| 平山县| 蒙自县| 舟山市| 连南| 阳新县| 句容市| 盐池县| 宜川县| 安远县| 玉门市| 七台河市| 塘沽区| 开化县| 房产| 利津县|