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

詳解springboot使用異步注解@Async獲取執(zhí)行結(jié)果的坑

 更新時(shí)間:2021年08月22日 09:31:21   作者:北漂程序員  
本文主要介紹了springboot使用異步注解@Async獲取執(zhí)行結(jié)果的坑,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

一、引言

在java后端開發(fā)中經(jīng)常會(huì)碰到處理多個(gè)任務(wù)的情況,比如一個(gè)方法中要調(diào)用多個(gè)請(qǐng)求,然后把多個(gè)請(qǐng)求的結(jié)果合并后統(tǒng)一返回,一般情況下調(diào)用其他的請(qǐng)求一般都是同步的,也就是每個(gè)請(qǐng)求都是阻塞的,那么這個(gè)處理時(shí)間必定是很長的,有沒有一種方法可以讓多個(gè)請(qǐng)求異步處理那,答案是有的。

springboot中提供了很便利的方式可以解決上面的問題,那就是異步注解@Async。正確的使用該注解可以使你的程序飛起,相反如果使用不當(dāng)那么并不會(huì)取到理想的效果。

二、獲取異步執(zhí)行結(jié)果

1、環(huán)境介紹

下面是我的controller,SyncController.java

package com.atssg.controller;

import com.atssg.service.MySyncService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@Slf4j
@RestController
@RequestMapping("/sync")
public class SyncController {
    @Autowired
    private MySyncService syncService;

    @GetMapping(value = "/test")

    public String test() {
        String str=null;
        try {

            log.info("start");
            str = syncService.asyncMethod();
            log.info("str:{}", str);
            return str;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return str;
    }
}

在controller中就是調(diào)用下層的方法并返回,再看service層的類MySyncService.java

package com.atssg.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

@Service
public class MySyncService {
    @Autowired
    private SyncService syncService;

    /**
     * 異步方法
     *
     * @return
     * @throws InterruptedException
     * @throws ExecutionException
     */
    public String asyncMethod() throws InterruptedException, ExecutionException {

        Future<String> result1 = syncService.method1("I");
        Future<String> result2 = syncService.method2("love");
        Future<String> result3 = syncService.method3("async");

        String str = result1.get();
        String str2 = result2.get();
        String str3 = result3.get();

        String result = str + str2 + str3;

        return result;
    }

    /**
     * 同步方法
     *
     * @return
     * @throws InterruptedException
     * @throws ExecutionException
     */
    public String syncMethod() throws InterruptedException, ExecutionException {
        /*同步寫法*/
        String str = syncService.method1("I").get();
        String str2 = syncService.method2("love").get();
        String str3 = syncService.method3("async").get();
        return str + str2 + str3;
    }
}

上面便是service類,僅僅是調(diào)用下次異步層的方法,并取得返回值。上面類中有兩個(gè)方法,其寫法也類似但結(jié)果卻大不相同,后面詳說。

下面是異步層的方法,SyncService.java

package com.atssg.service;

import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;

import java.util.concurrent.Future;

@Service
@Async
public class SyncService {

    //@Async
    public Future<String> method1(String str) throws InterruptedException {
       Thread.sleep(1000*10);
        return new AsyncResult<>( str);
    }
    //@Async
    public Future<String> method2(String str) throws InterruptedException {
        Thread.sleep(1000*5);
        return new AsyncResult<>(str);
    }
   // @Async
    public Future<String> method3(String str) throws InterruptedException {
        Thread.sleep(1000*15);
        return new AsyncResult<>(str);
    }
}

該類使用@Async注解,表明該類中所有的方法都是異步執(zhí)行的,其中@Async可修飾類也可以修飾方法。

這便是所有的環(huán)境。

2、錯(cuò)誤的方式

在MySyncService中有兩個(gè)方法,先看其中一個(gè)方法

public String syncMethod() throws InterruptedException, ExecutionException {
        /*同步寫法*/
        String str = syncService.method1("I").get();
        String str2 = syncService.method2("love").get();
        String str3 = syncService.method3("async").get();
        return str + str2 + str3;
    }

這種寫法是調(diào)用異步方法后立即調(diào)用get()方法,即獲取結(jié)果,下面看測(cè)試結(jié)果,在controllor中調(diào)用該方法,下面看執(zhí)行結(jié)果

2021-08-21 11:06:28.612  INFO 3584 --- [nio-8080-exec-1] com.atssg.controller.SyncController      : start
2021-08-21 11:06:58.651  INFO 3584 --- [nio-8080-exec-1] com.atssg.controller.SyncController      : str:Iloveasync

可以看到共執(zhí)行了30s,在異步層的方法中的三個(gè)方法如下,

//@Async
    public Future<String> method1(String str) throws InterruptedException {
       Thread.sleep(1000*10);
        return new AsyncResult<>( str);
    }
    //@Async
    public Future<String> method2(String str) throws InterruptedException {
        Thread.sleep(1000*5);
        return new AsyncResult<>(str);
    }
   // @Async
    public Future<String> method3(String str) throws InterruptedException {
        Thread.sleep(1000*15);
        return new AsyncResult<>(str);
    }

可以看到這三個(gè)方法分別是睡眠10s、5s、15s,這就很好理解了syncMethod()方法中的寫法是同步的,未達(dá)到異步的目的,切記調(diào)用完異步方法進(jìn)接著調(diào)用get()方法不是異步的方式,而是同步的。

3、正確方式

上面看了錯(cuò)誤的用法,下面看正確的方式,

 public String asyncMethod() throws InterruptedException, ExecutionException {

        Future<String> result1 = syncService.method1("I");
        Future<String> result2 = syncService.method2("love");
        Future<String> result3 = syncService.method3("async");

        String str = result1.get();
        String str2 = result2.get();
        String str3 = result3.get();

        String result = str + str2 + str3;

        return result;
    }

這種方式是首先調(diào)用異步方法,然后分別調(diào)用get()方法,取得執(zhí)行結(jié)果。下面看測(cè)試結(jié)果

2021-08-21 11:17:23.516  INFO 3248 --- [nio-8080-exec-1] com.atssg.controller.SyncController      : start
2021-08-21 11:17:38.535  INFO 3248 --- [nio-8080-exec-1] com.atssg.controller.SyncController      : str:Iloveasync

執(zhí)行時(shí)間未15s,這就很好解釋了,異步層的三個(gè)方法,分別睡眠的時(shí)間是10s、5s、15s,既然是異步執(zhí)行的,那么總的執(zhí)行時(shí)間肯定是三個(gè)方法中最長的那個(gè),符合測(cè)試結(jié)果。這才@Async正確的打開姿勢(shì)。

三、異步執(zhí)行@Async注解

@Async注解的定義如下,

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Async {
    String value() default "";
}

可以看到該注解可以用在類及方法上,用在類上表示類中的所有方法都是異步的,用在方法上表示該方法是異步的。

四、總結(jié)

今天的文章分享到這里,主要分享了關(guān)于@Async注解在獲取執(zhí)行結(jié)果的時(shí)候的坑,一定要先調(diào)用異步方法,然后再調(diào)用get()方法,獲取結(jié)果,其中g(shù)et方法還有一個(gè)重載的,可以設(shè)置超時(shí)時(shí)間,即超過設(shè)置的超時(shí)時(shí)間便返回,不再等待,各位小伙伴可以自己試驗(yàn)。

 V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

下次繼續(xù)分享有關(guān)@Async注解使用的一些小細(xì)節(jié),歡迎持續(xù)關(guān)注。

到此這篇關(guān)于詳解springboot使用異步注解@Async獲取執(zhí)行結(jié)果的坑的文章就介紹到這了,更多相關(guān)springboot使用異步注解@Async 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java的非對(duì)稱加密(RSA、數(shù)字簽名、數(shù)字證書)詳解

    Java的非對(duì)稱加密(RSA、數(shù)字簽名、數(shù)字證書)詳解

    這篇文章主要介紹了Java的非對(duì)稱加密(RSA、數(shù)字簽名、數(shù)字證書)詳解,非對(duì)稱加密:加密、解密使用不同的兩把密鑰,這兩把密鑰成對(duì),一般通信開始時(shí)通過非對(duì)稱加密將對(duì)稱加密的密鑰發(fā)送給另一方,然后雙方通過對(duì)稱加密來進(jìn)行溝通,需要的朋友可以參考下
    2024-01-01
  • Spring如何重寫內(nèi)置Bean(Controller、Service等)

    Spring如何重寫內(nèi)置Bean(Controller、Service等)

    本文介紹了在Spring Boot工程中處理外部JAR包中Controller方法重寫的需求,通過PostProcessor方式和自定義注解@ExcludeBean兩種方法,解決了在不修改源代碼的情況下重寫接口的問題
    2025-01-01
  • SpringBoot 創(chuàng)建web項(xiàng)目并部署到外部Tomcat

    SpringBoot 創(chuàng)建web項(xiàng)目并部署到外部Tomcat

    本篇文章主要介紹了SpringBoot 創(chuàng)建web項(xiàng)目并部署到外部Tomcat,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • 解決Springboot啟動(dòng)報(bào)錯(cuò):類文件具有錯(cuò)誤的版本61.0,應(yīng)為?52.0

    解決Springboot啟動(dòng)報(bào)錯(cuò):類文件具有錯(cuò)誤的版本61.0,應(yīng)為?52.0

    這篇文章主要給大家介紹了關(guān)于解決Springboot啟動(dòng)報(bào)錯(cuò):類文件具有錯(cuò)誤的版本?61.0,應(yīng)為?52.0的相關(guān)資料,這是查閱了網(wǎng)上的很多資料才解決的,分享給大家,需要的朋友可以參考下
    2023-01-01
  • nexus私服啟動(dòng)不了問題及解決

    nexus私服啟動(dòng)不了問題及解決

    這篇文章主要介紹了nexus私服啟動(dòng)不了問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Mybatis使用foreach批量更新數(shù)據(jù)報(bào)無效字符錯(cuò)誤問題

    Mybatis使用foreach批量更新數(shù)據(jù)報(bào)無效字符錯(cuò)誤問題

    這篇文章主要介紹了Mybatis使用foreach批量更新數(shù)據(jù)報(bào)無效字符錯(cuò)誤問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Java中的BigDecimal原理詳解

    Java中的BigDecimal原理詳解

    這篇文章主要介紹了Java中的BigDecimal原理詳解,對(duì)于日常開發(fā)過程中出現(xiàn)小數(shù)的問題,通常都是使用float或者double類型來處理,在java中float占用四個(gè)字節(jié), double類型占用8個(gè)字節(jié),需要的朋友可以參考下
    2023-09-09
  • SpringBoot集成DJL實(shí)現(xiàn)圖片分類功能

    SpringBoot集成DJL實(shí)現(xiàn)圖片分類功能

    DJL是一個(gè)使用Java?API簡化模型訓(xùn)練、測(cè)試、部署和使用深度學(xué)習(xí)模型進(jìn)行推理的開源庫深度學(xué)習(xí)工具包,開源的許可協(xié)議是Apache-2.0,本文給大家介紹了SpringBoot集成DJL實(shí)現(xiàn)圖片分類功能,需要的朋友可以參考下
    2024-10-10
  • Spring?Boot項(xiàng)目如何優(yōu)雅實(shí)現(xiàn)Excel導(dǎo)入與導(dǎo)出功能

    Spring?Boot項(xiàng)目如何優(yōu)雅實(shí)現(xiàn)Excel導(dǎo)入與導(dǎo)出功能

    在我們平時(shí)工作中經(jīng)常會(huì)遇到要操作Excel的功能,比如導(dǎo)出個(gè)用戶信息或者訂單信息的Excel報(bào)表,下面這篇文章主要給大家介紹了關(guān)于Spring?Boot項(xiàng)目中如何優(yōu)雅實(shí)現(xiàn)Excel導(dǎo)入與導(dǎo)出功能的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • Java排序算法之SleepSort排序示例

    Java排序算法之SleepSort排序示例

    這篇文章主要介紹了Java排序算法之SleepSort排序,結(jié)合實(shí)例形式分析了SleepSort排序的實(shí)現(xiàn)步驟與相關(guān)操作技巧,需要的朋友可以參考下
    2017-01-01

最新評(píng)論

拉萨市| 莱阳市| 台湾省| 同江市| 青岛市| 沁阳市| 华亭县| 砚山县| 黑水县| 镇平县| 郎溪县| 新巴尔虎右旗| 江都市| 高邮市| 汽车| 日土县| 上思县| 安吉县| 五原县| 榆林市| 吴川市| 龙井市| 湟中县| 泌阳县| 邮箱| 邛崃市| 罗山县| 中江县| 石狮市| 财经| 吉安市| 青海省| 汶川县| 唐山市| 南阳市| 鲁甸县| 定州市| 都昌县| 越西县| 青州市| 宁国市|