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

詳解springboot通過Async注解實現(xiàn)異步任務及回調(diào)的方法

 更新時間:2022年05月11日 10:05:58   作者:字母哥哥  
這篇文章主要介紹了springboot通過Async注解實現(xiàn)異步任務及回調(diào),文中通過一個簡單示例來直觀的理解什么是同步調(diào)用,在單元測試用例中,注入?SyncTask?對象,并在測試用例中執(zhí)行?doTaskOne(),doTaskTwo(),doTaskThree()?三個方法,具體實現(xiàn)方式跟隨小編一起看看吧

前言

什么是異步調(diào)用?

異步調(diào)用是相對于同步調(diào)用而言的,同步調(diào)用是指程序按預定順序一步步執(zhí)行,每一步必須等到上一步執(zhí)行完后才能執(zhí)行,異步調(diào)用則無需等待上一步程序執(zhí)行完即可執(zhí)行。異步調(diào)用可以減少程序執(zhí)行時間。

1. 環(huán)境準備

在這里插入圖片描述

Spring Boot 入口類上配置 @EnableAsync 注解開啟異步處理。
創(chuàng)建任務抽象類 AbstractTask,并實現(xiàn)三個任務方法 doTaskOne()doTaskTwo(),doTaskThree()。

public abstract class AbstractTask {
    private static Random random = new Random();
    public void doTaskOne() throws Exception {
        System.out.println("開始做任務一");
        long start = currentTimeMillis();
        sleep(random.nextInt(10000));
        long end = currentTimeMillis();
        System.out.println("完成任務一,耗時:" + (end - start) + "毫秒");
    }
    public void doTaskTwo() throws Exception {
        System.out.println("開始做任務二");
        long start = currentTimeMillis();
        sleep(random.nextInt(10000));
        long end = currentTimeMillis();
        System.out.println("完成任務二,耗時:" + (end - start) + "毫秒");
    }
    public void doTaskThree() throws Exception {
        System.out.println("開始做任務三");
        long start = currentTimeMillis();
        sleep(random.nextInt(10000));
        long end = currentTimeMillis();
        System.out.println("完成任務三,耗時:" + (end - start) + "毫秒");
    }
}

2. 同步調(diào)用

下面通過一個簡單示例來直觀的理解什么是同步調(diào)用:

定義 Task 類,繼承 AbstractTask,三個處理函數(shù)分別模擬三個執(zhí)行任務的操作,操作消耗時間隨機取(10 秒內(nèi))。

@Component
public class SyncTask extends AbstractTask {
}

單元測試 用例中,注入 SyncTask 對象,并在測試用例中執(zhí)行 doTaskOne()doTaskTwo(),doTaskThree() 三個方法。

@RunWith(SpringRunner.class)
@SpringBootTest
public class TaskTest {
    @Autowired
    private SyncTask task;
    @Test
    public void testSyncTasks() throws Exception {
        task.doTaskOne();
        task.doTaskTwo();
        task.doTaskThree();
    }
}

執(zhí)行單元測試,可以看到類似如下輸出:

開始做任務一
完成任務一,耗時:6720毫秒
開始做任務二
完成任務二,耗時:6604毫秒
開始做任務三
完成任務三,耗時:9448毫秒

在這里插入圖片描述

任務一、任務二、任務三順序的執(zhí)行完了,換言之 doTaskOne(),doTaskTwo(),doTaskThree() 三個方法按調(diào)用順序的先后執(zhí)行完成。

3. 異步調(diào)用

上述的 同步調(diào)用 雖然順利的執(zhí)行完了三個任務,但是可以看到 執(zhí)行時間比較長,若這三個任務本身之間 不存在依賴關系,可以 并發(fā)執(zhí)行 的話,同步調(diào)用在 執(zhí)行效率 方面就比較差,可以考慮通過 異步調(diào)用 的方式來 并發(fā)執(zhí)行。

  • 在Application啟動類上面加上@EnableAsync
  • 創(chuàng)建 AsyncTask類,分別在方法上配置 @Async 注解,將原來的 同步方法 變?yōu)?異步方法
@Component
public class AsyncTask extends AbstractTask {
    @Async
    public void doTaskOne() throws Exception {
        super.doTaskOne();
    }
    @Async
    public void doTaskTwo() throws Exception {
        super.doTaskTwo();
    }
    @Async
    public void doTaskThree() throws Exception {
        super.doTaskThree();
    }
}

單元測試 用例中,注入 AsyncTask 對象,并在測試用例中執(zhí)行 doTaskOne(),doTaskTwo()doTaskThree() 三個方法。

@Autowired
private AsyncTask asyncTask;
@Test
public void testAsyncTasks() throws Exception {
    asyncTask.doTaskOne();
    asyncTask.doTaskTwo();
    asyncTask.doTaskThree();
}

執(zhí)行單元測試,可以看到類似如下輸出:

開始做任務三
開始做任務一
開始做任務二

如果反復執(zhí)行單元測試,可能會遇到各種不同的結(jié)果,比如:

  • 沒有任何任務相關的輸出
  • 有部分任務相關的輸出
  • 亂序的任務相關的輸出

在這里插入圖片描述

原因是目前 doTaskOne(),doTaskTwo()doTaskThree() 這三個方法已經(jīng) 異步并發(fā)執(zhí)行 了。主程序在 異步調(diào)用 之后,主程序并不會理會這三個函數(shù)是否執(zhí)行完成了,由于沒有其他需要執(zhí)行的內(nèi)容,所以程序就 自動結(jié)束 了,導致了任務 不完整 或是 沒有輸出 相關內(nèi)容的情況。

注意:@Async所修飾的函數(shù)不要定義為static類型,這樣異步調(diào)用不會生效。

4. 異步回調(diào)

為了讓 doTaskOne(),doTaskTwo(),doTaskThree() 能正常結(jié)束,假設我們需要統(tǒng)計一下三個任務 并發(fā)執(zhí)行 共耗時多少,這就需要等到上述三個函數(shù)都完成動用之后記錄時間,并計算結(jié)果。

那么我們?nèi)绾闻袛嗌鲜鋈齻€ 異步調(diào)用 是否已經(jīng)執(zhí)行完成呢?我們需要使用 Future<T> 來返回 異步調(diào)用結(jié)果。

  • 創(chuàng)建 AsyncCallBackTask 類,聲明 doTaskOneCallback(),doTaskTwoCallback()doTaskThreeCallback() 三個方法,對原有的三個方法進行包裝。
@Component
public class AsyncCallBackTask extends AbstractTask {
    @Async
    public Future<String> doTaskOneCallback() throws Exception {
        super.doTaskOne();
        return new AsyncResult<>("任務一完成");
    }
    @Async
    public Future<String> doTaskTwoCallback() throws Exception {
        super.doTaskTwo();
        return new AsyncResult<>("任務二完成");
    }
    @Async
    public Future<String> doTaskThreeCallback() throws Exception {
        super.doTaskThree();
        return new AsyncResult<>("任務三完成");
    }
}

單元測試 用例中,注入 AsyncCallBackTask 對象,并在測試用例中執(zhí)行 doTaskOneCallback(),doTaskTwoCallback(),doTaskThreeCallback() 三個方法。循環(huán)調(diào)用 FutureisDone() 方法等待三個 并發(fā)任務 執(zhí)行完成,記錄最終執(zhí)行時間。

@Autowired
private AsyncCallBackTask asyncCallBackTask;
@Test
public void testAsyncCallbackTask() throws Exception {
    long start = currentTimeMillis();
    Future<String> task1 = asyncCallBackTask.doTaskOneCallback();
    Future<String> task2 = asyncCallBackTask.doTaskTwoCallback();
    Future<String> task3 = asyncCallBackTask.doTaskThreeCallback();
    // 三個任務都調(diào)用完成,退出循環(huán)等待
    while (!task1.isDone() || !task2.isDone() || !task3.isDone()) {
        sleep(1000);
    }
    long end = currentTimeMillis();
    System.out.println("任務全部完成,總耗時:" + (end - start) + "毫秒");
}

看看都做了哪些改變:

  • 在測試用例一開始記錄開始時間;
  • 在調(diào)用三個異步函數(shù)的時候,返回Future類型的結(jié)果對象;
  • 在調(diào)用完三個異步函數(shù)之后,開啟一個循環(huán),根據(jù)返回的Future對象來判斷三個異步函數(shù)是否都結(jié)束了。若都結(jié)束,就結(jié)束循環(huán);若沒有都結(jié)束,就等1秒后再判斷。
  • 跳出循環(huán)之后,根據(jù)結(jié)束時間 - 開始時間,計算出三個任務并發(fā)執(zhí)行的總耗時。

在這里插入圖片描述

執(zhí)行一下上述的單元測試,可以看到如下結(jié)果:

開始做任務三
開始做任務一
開始做任務二
完成任務二,耗時:2572毫秒
完成任務一,耗時:7333毫秒
完成任務三,耗時:7647毫秒
任務全部完成,總耗時:8013毫秒

到此這篇關于springboot通過Async注解實現(xiàn)異步任務及回調(diào)的文章就介紹到這了,更多相關springboot Async注解異步任務內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • mybatis trim標簽的使用詳解

    mybatis trim標簽的使用詳解

    這篇文章主要介紹了mybatis trim標簽的使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-06-06
  • Java中Json解析的方法分析

    Java中Json解析的方法分析

    這篇文章主要介紹了Java中Json解析的方法,結(jié)合實例形式分析了java針對json格式數(shù)據(jù)的解析實現(xiàn)步驟與相關操作技巧,需要的朋友可以參考下
    2017-05-05
  • JAVA中數(shù)組插入與刪除指定元素的實例代碼

    JAVA中數(shù)組插入與刪除指定元素的實例代碼

    下面小編就為大家分享一篇JAVA中數(shù)組插入與刪除指定元素的實例代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-02-02
  • Java集合之整體結(jié)構(gòu)

    Java集合之整體結(jié)構(gòu)

    Java中集合類是Java編程中使用最頻繁、最方便的類。接下來通過本文給大家介紹Java集合之整體結(jié)構(gòu),一起看看吧
    2016-05-05
  • java數(shù)據(jù)結(jié)構(gòu)基礎:緒論

    java數(shù)據(jù)結(jié)構(gòu)基礎:緒論

    這篇文章主要介紹了Java的數(shù)據(jù)解構(gòu)基礎,希望對廣大的程序愛好者有所幫助,同時祝大家有一個好成績,需要的朋友可以參考下,希望能給你帶來幫助
    2021-07-07
  • Java IO流之Properties類的使用

    Java IO流之Properties類的使用

    這篇文章主要介紹了Java IO流之Properties類的使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • java實現(xiàn)發(fā)送郵箱驗證碼

    java實現(xiàn)發(fā)送郵箱驗證碼

    這篇文章主要為大家詳細介紹了java實現(xiàn)發(fā)送郵箱驗證碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • java17日期周期格式化處理方案

    java17日期周期格式化處理方案

    Java17引入了新的日期時間格式化模式B,用于表示一天中的時間段,如上午、下午、晚上等,該模式根據(jù)CLDR定義,在不同語言環(huán)境下,該模式的輸出結(jié)果會有所不同,本文給大家介紹java17日期周期格式化處理方案,感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • FasfDFS整合Java實現(xiàn)文件上傳下載功能實例詳解

    FasfDFS整合Java實現(xiàn)文件上傳下載功能實例詳解

    這篇文章主要介紹了FasfDFS整合Java實現(xiàn)文件上傳下載功能實例詳解,需要的朋友可以參考下
    2017-08-08
  • OpenJDK源碼解析之System.out.println詳解

    OpenJDK源碼解析之System.out.println詳解

    這篇文章主要介紹了OpenJDK源碼解析之System.out.println詳解,文中有非常詳細的代碼示例,對正在學習java的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04

最新評論

秦安县| 比如县| 普陀区| 江川县| 福安市| 巫山县| 尼木县| 通化县| 青田县| 隆安县| 济源市| 依兰县| 马公市| 新宾| 江安县| 桂东县| 友谊县| 普兰县| 佛坪县| 义乌市| 南郑县| 黄浦区| 黄梅县| 乾安县| 泸水县| 长泰县| 库车县| 南投县| 梁山县| 阳西县| 神木县| 赤峰市| 澳门| 阳泉市| 凌源市| 洛阳市| 汶川县| 开封县| 阿巴嘎旗| 新营市| 吉安市|