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

Java SpringMVC異步處理詳解

 更新時間:2021年10月26日 15:17:07   作者:路人甲Java  
這篇文章主要介紹了Java springmvc的處理異步,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

1、本篇內(nèi)容

本文讓大家掌握 springmvc 中異步處理請求,特別牛逼的一個功能,大家一定要掌握。

2、看段代碼,分析問題

@ResponseBody
@RequestMapping("/async/m1.do")
public String m1() throws InterruptedException {
    long st = System.currentTimeMillis();
    System.out.println("主線程:" + Thread.currentThread() + "," + st + ",開始");
    //休眠3秒,模擬耗時的業(yè)務(wù)操作
    TimeUnit.SECONDS.sleep(3);
    long et = System.currentTimeMillis();
    System.out.println("主線程:" + Thread.currentThread() + "," + st + ",結(jié)束,耗時(ms):" + (et - st));
    return "ok";
}

這段代碼很簡單

這段代碼是 springmvc 提供的一個接口

內(nèi)部休眠了 3 秒鐘,用來模擬耗時的操作

方法內(nèi)部有 2 條日志(日志中包含了當(dāng)前線程、開始時間、結(jié)束時間、耗時)

瀏覽器中訪問下這個接口,效果如下,可以看到接口耗時 3s 左右。

控制臺輸出

主線程:Thread[http-nio-8080-exec-1,5,main],1624889293055,開始
主線程:Thread[http-nio-8080-exec-1,5,main],1624889293055,結(jié)束,耗時(ms):3002

從輸出中,我們可以看出,這個接口從開始到結(jié)束都是由 tomcat 中的線程來處理用戶請求的,也就是說,3 秒這段時間內(nèi),tomcat 中的一個線程會被當(dāng)前請求一直占用了則,tomcat 線程是有最大值的,默認(rèn)情況下好像是 75,那么問題來了。

當(dāng) 3 秒之內(nèi),來的請求數(shù)量超過了 tomcat 最大線程數(shù)的時候,其他請求就無法處理了,而此時 tomcat 中這些線程都處理 sleep 3s 的休眠狀態(tài),cpu 此時沒活干,此時就會造成機(jī)器沒活干,但是呢又不能處理新的請求,這就是坑啊,浪費資源,怎么辦呢?

遇到這種場景的,也就是說接口內(nèi)部比價耗時,但是又不能充分利用 cpu 的,我們可以采用異步的方式來處理請求,過程如下:

tomcat 線程,將請求轉(zhuǎn)發(fā)給我們自定義的子線程去處理這個請求,然后 tomcat 就可以繼續(xù)去接受新的請求了。

3、springmvc 中異步處理

主要有 3 個大的步驟。

step1:servlet 開啟異步處理支持

web.xml 中開啟 servlet 異步支持

step2:Filter 中添加異步支持

如果我們的異步請求需要經(jīng)過 Filter 的,那么需要在 web.xml 對這個 Filter 添加異步支持.

step3:接口返回值為 DeferredResult

這個步驟中細(xì)節(jié)比較多,當(dāng)需要異步響應(yīng)請求的時候,返回值需要為 DeferredResult,具體參考下面案例代碼,詳細(xì)信息都在注釋中了,大家注意看注釋。

第 1 步:創(chuàng)建 DeferredResult<返回值類型>(超時時間[毫秒],超時回調(diào)的代碼)

第 2 步:在子線程中異步處理業(yè)務(wù),調(diào)用 DeferredResult 的 setResult 方法,設(shè)置最終返回到客戶端的結(jié)果,此方法調(diào)用以后,客戶端將接收到返回值,然后響應(yīng)過程請求就結(jié)束了

第 3 步:將 DefaultResult 作為方法返回值

/**
 * 使用springmvc的異步功能,業(yè)務(wù)處理放在異步線程中執(zhí)行
 *
 * @param timeout 異步處理超時時間(毫秒)
 * @return
 */
@ResponseBody
@RequestMapping("/async/m2/{timeout}.do")
public DeferredResult m2(@PathVariable("timeout") long timeout) {
    long st = System.currentTimeMillis();
    System.out.println("主線程:" + Thread.currentThread() + "," + st + ",開始");
    /**
     * 1、創(chuàng)建DeferredResult<返回值類型>(超時時間[毫秒],超時回調(diào)的代碼)
     */
    DeferredResult result = new DeferredResult(timeout, () -> {
        System.out.println("超時了");
        return "timeout";
    });
    //2、異步處理業(yè)務(wù),
    new Thread(() -> {
        //開啟一個異步線程,在異步線程中進(jìn)行業(yè)務(wù)處理操作
        try {
            TimeUnit.SECONDS.sleep(3);
            //3、調(diào)用DeferredResult的setResult方法,設(shè)置最終返回到客戶端的結(jié)果,此方法調(diào)用以后,客戶端將接收到返回值
            result.setResult("ok");
        } catch (InterruptedException e) {
            result.setResult("發(fā)生異常了:" + e.getMessage());
        }
    }).start();
    long et = System.currentTimeMillis();
    System.out.println("主線程:" + Thread.currentThread() + "," + st + ",結(jié)束,耗時(ms):" + (et - st));
    //3、將DefaultResult作為方法返回值
    return result;
}

上面的 m2 方法個 timeout 參數(shù),調(diào)用者通過這個參數(shù)來指定接口的超時時間,未超時的情況下,也就是說 timeout 大于 3 秒的時候,此時會輸出 ok,否則將出現(xiàn)超時,此時會將 DeferredResult 構(gòu)造器第 2 個參數(shù)的執(zhí)行結(jié)果作為最終的響應(yīng)結(jié)果,即會向客戶端輸出 timeout。

使用建議:案例開啟了一個新的子線程來執(zhí)行業(yè)務(wù)操作,生產(chǎn)環(huán)境中,建議大家采用線程池的方式,效率更高。

下面我們來通過 2 個 case 來模擬下這個接口超時和正常的結(jié)果。

4、模擬非超時請求

當(dāng) timeout 大于 3 秒時,才不會出現(xiàn)超時,此時我們傳遞 4000 毫秒來試試

控制臺輸出如下,可以看到主線程瞬間就結(jié)束了。

主線程:Thread[http-nio-8080-exec-6,5,main],1624891886020,開始
主線程:Thread[http-nio-8080-exec-6,5,main],1624891886020,結(jié)束,耗時(ms):0

5、模擬超時請求

當(dāng) timeout 小于 3 秒會出現(xiàn)超時,此時我們傳遞 1000 毫秒來試試

控制臺輸出如下,輸出了超時信息,且通過前兩行輸出看出主線程瞬間就結(jié)束了,不會被請求阻塞。

主線程:Thread[http-nio-8080-exec-1,5,main],1624892109695,開始
主線程:Thread[http-nio-8080-exec-1,5,main],1624892109695,結(jié)束,耗時(ms):0
超時了

6、總結(jié)

當(dāng)接口中有大量的耗時的操作,且這些耗時的操作讓線程處于等待狀態(tài)時,此時為了提升系統(tǒng)的性能,可以將接口調(diào)整為異步處理的方式。

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • spring Boot查詢數(shù)據(jù)分頁顯示的方法實例

    spring Boot查詢數(shù)據(jù)分頁顯示的方法實例

    這篇文章主要給大家介紹了關(guān)于spring Boot查詢數(shù)據(jù)分頁顯示的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用spring Boot具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • Hibernate映射解析之關(guān)聯(lián)映射詳解

    Hibernate映射解析之關(guān)聯(lián)映射詳解

    所謂關(guān)聯(lián)映射就是將關(guān)聯(lián)關(guān)系映射到數(shù)據(jù)庫里,在對象模型中就是一個或多個引用。下面這篇文章詳細(xì)的給大家介紹了Hibernate映射解析之關(guān)聯(lián)映射的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-02-02
  • 關(guān)于@SpringBootApplication詳解

    關(guān)于@SpringBootApplication詳解

    這篇文章主要介紹了關(guān)于@SpringBootApplication的使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Spring Boot高可用限流三種實現(xiàn)解決方案

    Spring Boot高可用限流三種實現(xiàn)解決方案

    限流是對某一時間窗口內(nèi)的請求數(shù)進(jìn)行限制,保持系統(tǒng)的可用性和穩(wěn)定性,本文就介紹了Spring Boot高可用限流三種實現(xiàn)解決方案,具有一定的參考價值,感興趣的可以了解一下
    2023-08-08
  • Java彈簧布局管理器使用方法詳解

    Java彈簧布局管理器使用方法詳解

    這篇文章主要介紹了Java彈簧布局管理器使用方法詳解,需要的朋友可以參考下
    2017-09-09
  • 教你怎么用Java數(shù)組和鏈表實現(xiàn)棧

    教你怎么用Java數(shù)組和鏈表實現(xiàn)棧

    本篇文章為大家詳細(xì)介紹了怎么用Java數(shù)組和鏈表實現(xiàn)棧,文中有非常詳細(xì)的代碼示例及注釋,對正在學(xué)習(xí)java的小伙伴們很有幫助,需要的朋友可以參考下
    2021-05-05
  • SpringMVC xml文件路徑在web.xml中的配置方式

    SpringMVC xml文件路徑在web.xml中的配置方式

    這篇文章主要介紹了SpringMVC xml文件路徑在web.xml中的配置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Mybatis-plus apply函數(shù)使用場景分析

    Mybatis-plus apply函數(shù)使用場景分析

    Mybatis-plus 里面的 apply方法 是用于拼接自定義的條件判斷,自定義時間查詢,根據(jù)傳進(jìn)來的開始日期,查詢所有該日期是數(shù)據(jù),但是數(shù)據(jù)庫中保存是時間,所以需要使用apply查詢方式并格式化,這篇文章給大家介紹Mybatis-plus apply函數(shù)使用,感興趣的朋友一起看看吧
    2024-02-02
  • MyBatis?實現(xiàn)多對多中間表插入數(shù)據(jù)

    MyBatis?實現(xiàn)多對多中間表插入數(shù)據(jù)

    這篇文章主要介紹了MyBatis?實現(xiàn)多對多中間表插入數(shù)據(jù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • java反射總結(jié)實例詳解

    java反射總結(jié)實例詳解

    這篇文章主要結(jié)合實例形式分析了介紹了java基于反射得到對象屬性值的方法,Class類,基本數(shù)據(jù)類型,類的反射等,需要的朋友可以參考下
    2017-04-04

最新評論

平湖市| 教育| 潼南县| 通河县| 桦甸市| 江源县| 青神县| 常宁市| 翼城县| 娄烦县| 炎陵县| 米林县| 张掖市| 潞西市| 图片| 苍山县| 宜昌市| 视频| 江川县| 天峻县| 上林县| 会昌县| 富锦市| 滦平县| 杭锦后旗| 萍乡市| 肇东市| 芷江| 阿勒泰市| 卢湾区| 正宁县| 抚州市| 钟祥市| 武邑县| 卓尼县| 英吉沙县| 南宫市| 江油市| 顺义区| 盐津县| 仁布县|