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

詳解Java8?CompletableFuture的并行處理用法

 更新時(shí)間:2022年04月27日 14:18:13   作者:Java分享客棧  
Java8中有一個(gè)工具非常有用,那就是CompletableFuture,本章主要講解CompletableFuture的并行處理用法,感興趣的小伙伴可以了解一下

前言

工作中你可能會(huì)遇到很多這樣的場(chǎng)景,一個(gè)接口,要從其他幾個(gè)service調(diào)用查詢方法,分別獲取到需要的值之后再封裝數(shù)據(jù)返回。

還可能在微服務(wù)中遇到類(lèi)似的情況,某個(gè)服務(wù)的接口,要使用好幾次feign去調(diào)用其他服務(wù)的方法獲取數(shù)據(jù),最后拿到想要的值并封裝返回給前端。

這樣的場(chǎng)景下,當(dāng)某個(gè)或多個(gè)rpc調(diào)用的方法比較耗時(shí),整個(gè)接口的響應(yīng)就會(huì)非常慢。Java8之后,有一個(gè)工具非常適合處理這種場(chǎng)景,就是CompletableFuture。

場(chǎng)景

本章主要講解CompletableFuture的并行處理用法,來(lái)針對(duì)這種很常見(jiàn)的場(chǎng)景,幫助大家快速掌握并應(yīng)用到實(shí)際工作當(dāng)中。CompletableFuture內(nèi)部的用法還有許多,但個(gè)人用到的場(chǎng)景大多都是并行處理,對(duì)其他場(chǎng)景感興趣的小伙伴可以另行百度搜索。

場(chǎng)景說(shuō)明:

寫(xiě)一個(gè)接口,調(diào)用另外兩個(gè)HTTP接口,分別獲取二十四節(jié)氣和星座,最后放在一起返回。

用法

1、在線API

我們?cè)L問(wèn)極速數(shù)據(jù)網(wǎng)站,注冊(cè)一個(gè)賬號(hào),就可以免費(fèi)使用里面的一些在線API,平均每天有100次免費(fèi)機(jī)會(huì),對(duì)于我這樣經(jīng)常本地做一些測(cè)試的人來(lái)說(shuō)完全夠用了。

這里,我使用了其中的查詢二十四節(jié)氣API,和查詢星座API,后面會(huì)提供案例代碼,也可以直接使用我的。

2、編寫(xiě)在線API查詢

這里,我們?cè)诓樵儠r(shí),模擬耗時(shí)的情況。

1.查詢二十四節(jié)氣

package com.example.async.service;

import cn.hutool.http.HttpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 查詢二十四節(jié)氣的服務(wù)
 * </p>
 *
 * @author 福隆苑居士,公眾號(hào):【Java分享客?!?
 * @since 2022-04-26 15:25
 */
@Service
@Slf4j
public class TwentyFourService {

   public static final String APPKEY = "xxxxxx";// 你的appkey
   public static final String URL = "https://api.jisuapi.com/jieqi/query";

   public String getResult() {
       String url = URL + "?appkey=" + APPKEY;
       String result = HttpUtil.get(url);

       // 模擬耗時(shí)
       try {
          TimeUnit.SECONDS.sleep(5);
       } catch (Exception e) {
          log.error("[二十四節(jié)氣]>>>> 異常: {}", e.getMessage(), e);
       }

       return result;
   }
   
}

2.查詢星座

package com.example.async.service;

import cn.hutool.http.HttpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 查詢星座的服務(wù)
 * </p>
 *
 * @author 福隆苑居士,公眾號(hào):【Java分享客?!?
 * @since 2022-04-26 15:25
 */
@Service
@Slf4j
public class ConstellationService {
   public static final String APPKEY = "xxxxxx";// 你的appkey
   public static final String URL = "https://api.jisuapi.com/astro/all";

   public String getResult() {

      String url = URL + "?appkey=" + APPKEY;
      String result = HttpUtil.get(url);

      // 模擬耗時(shí)
      try {
         TimeUnit.SECONDS.sleep(5);
      } catch (Exception e) {
         log.error("[星座]>>>> 異常: {}", e.getMessage(), e);
      }

      return result;
   }
   
}

3、編寫(xiě)查詢服務(wù)

package com.example.async.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 查詢服務(wù)
 * </p>
 *
 * @author 福隆苑居士,公眾號(hào):【Java分享客棧】
 * @since 2022-04-26 17:38
 */
@Service
@Slf4j
public class QueryService {
   private final TwentyFourService twentyFourService;
   private final ConstellationService constellationService;

   public QueryService(TwentyFourService twentyFourService, ConstellationService constellationService) {
      this.twentyFourService = twentyFourService;
      this.constellationService = constellationService;
   }

   /**
    * 同步返回結(jié)果
    * @return 結(jié)果
    */
   public Map<String, Object> query() {
      // 1、查詢二十四節(jié)氣
      String twentyFourResult = twentyFourService.getResult();

      // 2、查詢星座
      String constellationResult = constellationService.getResult();

      // 3、返回
      Map<String, Object> map = new HashMap<>();
      map.put("twentyFourResult", twentyFourResult);
      map.put("constellationResult", constellationResult);
      return map;
   }
}

4、編寫(xiě)測(cè)試接口

這里,我們專門(mén)加上了耗時(shí)計(jì)算。

package com.example.async.controller;

import cn.hutool.core.date.TimeInterval;
import com.example.async.service.QueryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
 * <p>
 * 測(cè)試
 * </p>
 *
 * @author 福隆苑居士,公眾號(hào):【Java分享客?!?
 * @since 2022-04-26 17:35
 */
@RestController
@RequestMapping("/api")
@Slf4j
public class TestController {

   private final QueryService queryService;

   public TestController(QueryService queryService) {
      this.queryService = queryService;
   }

   /**
    * 同步查詢
    * @return 結(jié)果
    */
   @GetMapping("/query")
   public ResponseEntity<Map<String, Object>> query() {
      // 計(jì)時(shí)
      final TimeInterval timer = new TimeInterval();
      timer.start();
      Map<String, Object> map = queryService.query();
      map.put("costTime", timer.intervalMs() + " ms");
      return ResponseEntity.ok().body(map);
   }
}

5、效果

可以看到,兩個(gè)接口一共耗費(fèi)了10秒左右才返回。

6、CompletableFuture并行查詢

現(xiàn)在我們來(lái)使用CompletableFuture改造下接口,并行查詢兩個(gè)HTTP接口再返回。

package com.example.async.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * <p>
 * 查詢服務(wù)
 * </p>
 *
 * @author 福隆苑居士,公眾號(hào):【Java分享客?!?
 * @since 2022-04-26 17:38
 */
@Service
@Slf4j
public class QueryService {
   private final TwentyFourService twentyFourService;
   private final ConstellationService constellationService;

   public QueryService(TwentyFourService twentyFourService, ConstellationService constellationService) {
      this.twentyFourService = twentyFourService;
      this.constellationService = constellationService;
   }

   /**
    * 異步返回結(jié)果
    * @return 結(jié)果
    */
   public Map<String, Object> queryAsync() {

      Map<String, Object> map = new HashMap<>();

      // 1、查詢二十四節(jié)氣
      CompletableFuture<String> twentyFourQuery = CompletableFuture.supplyAsync(twentyFourService::getResult);
      twentyFourQuery.thenAccept((result) -> {
         log.info("查詢二十四節(jié)氣結(jié)果:{}", result);
         map.put("twentyFourResult", result);
      }).exceptionally((e) -> {
         log.error("查詢二十四節(jié)氣異常: {}", e.getMessage(), e);
         map.put("twentyFourResult", "");
         return null;
      });

      // 2、查詢星座
      CompletableFuture<String> constellationQuery = CompletableFuture.supplyAsync(constellationService::getResult);
      constellationQuery.thenAccept((result) -> {
         log.info("查詢星座結(jié)果:{}", result);
         map.put("constellationResult", result);
      }).exceptionally((e) -> {
         log.error("查詢星座異常: {}", e.getMessage(), e);
         map.put("constellationResult", "");
         return null;
      });

      // 3、allOf-兩個(gè)查詢必須都完成
      CompletableFuture<Void> allQuery = CompletableFuture.allOf(twentyFourQuery, constellationQuery);
      CompletableFuture<Map<String, Object>> future = allQuery.thenApply((result) -> {
         log.info("------------------ 全部查詢都完成 ------------------ ");
         return map;
      }).exceptionally((e) -> {
         log.error(e.getMessage(), e);
         return null;
      });

      // 獲取異步方法返回值
      // get()-內(nèi)部拋出了異常需手動(dòng)處理; join()-內(nèi)部處理了異常無(wú)需手動(dòng)處理,點(diǎn)進(jìn)去一看便知。
      future.join();

      return map;
   }
}

7、編寫(xiě)測(cè)試接口

package com.example.async.controller;

import cn.hutool.core.date.TimeInterval;
import com.example.async.service.QueryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
 * <p>
 * 測(cè)試
 * </p>
 *
 * @author 福隆苑居士,公眾號(hào):【Java分享客棧】
 * @since 2022-04-26 17:35
 */
@RestController
@RequestMapping("/api")
@Slf4j
public class TestController {

   private final QueryService queryService;

   public TestController(QueryService queryService) {
      this.queryService = queryService;
   }

   /**
    * 異步查詢
    * @return 結(jié)果
    */
   @GetMapping("/queryAsync")
   public ResponseEntity<Map<String, Object>> queryAsync() {
      // 計(jì)時(shí)
      final TimeInterval timer = new TimeInterval();
      timer.start();
      Map<String, Object> map = queryService.queryAsync();
      map.put("costTime", timer.intervalMs() + " ms");
      return ResponseEntity.ok().body(map);
   }
}

8、CompletableFuture效果

可以看到,時(shí)間縮短了一倍。

思考

如果在微服務(wù)中,有一個(gè)很復(fù)雜的業(yè)務(wù)需要遠(yuǎn)程調(diào)用5個(gè)第三方laji廠家的接口,每個(gè)接口假設(shè)都耗時(shí)5秒,使用CompletableFuture并行處理最終需要多久?

答案是肯定的,同步查詢需要25秒左右,CompletableFuture并行處理還是5秒左右,也就是說(shuō),同一個(gè)接口中,調(diào)用的耗時(shí)接口越多,CompletableFuture優(yōu)化的幅度就越大。

示例代碼

可以下載我的完整示例代碼本地按需測(cè)試,里面有我的極速數(shù)據(jù)API的key,省得自己注冊(cè)賬號(hào)了,每天免費(fèi)就100次,先到先得哦。

到此這篇關(guān)于詳解Java8 CompletableFuture的并行處理用法的文章就介紹到這了,更多相關(guān)Java8 CompletableFuture內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot中的404錯(cuò)誤:原因、影響及解決策略

    SpringBoot中的404錯(cuò)誤:原因、影響及解決策略

    本文詳細(xì)介紹了SpringBoot中404錯(cuò)誤的出現(xiàn)原因、影響以及處理策略,404錯(cuò)誤常見(jiàn)于URL路徑錯(cuò)誤、控制器配置問(wèn)題、靜態(tài)資源配置錯(cuò)誤、依賴缺失或版本不兼容、配置錯(cuò)誤和服務(wù)器配置問(wèn)題,解決方法包括檢查URL路徑、審查控制器配置、配置靜態(tài)資源
    2025-02-02
  • Spring boot實(shí)現(xiàn)應(yīng)用打包部署的示例

    Spring boot實(shí)現(xiàn)應(yīng)用打包部署的示例

    本篇文章主要介紹了Spring boot實(shí)現(xiàn)應(yīng)用打包部署的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-11-11
  • Java Springboot自動(dòng)裝配原理詳解

    Java Springboot自動(dòng)裝配原理詳解

    這篇文章主要介紹了詳解SpringBoot自動(dòng)配置原理,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2021-10-10
  • 怎樣使用PowerMockito 測(cè)試靜態(tài)方法

    怎樣使用PowerMockito 測(cè)試靜態(tài)方法

    這篇文章主要介紹了使用PowerMockito 測(cè)試靜態(tài)的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 詳解Java8新特性Stream之list轉(zhuǎn)map及問(wèn)題解決

    詳解Java8新特性Stream之list轉(zhuǎn)map及問(wèn)題解決

    這篇文章主要介紹了詳解Java8新特性Stream之list轉(zhuǎn)map及問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • 解決Eclipse配置Tomcat出現(xiàn)Cannot create a server using the selected type錯(cuò)誤

    解決Eclipse配置Tomcat出現(xiàn)Cannot create a server using the selected

    這篇文章主要介紹了解決Eclipse配置Tomcat出現(xiàn)Cannot create a server using the selected type錯(cuò)誤的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • SpringBoot3.X配置OAuth的代碼實(shí)踐

    SpringBoot3.X配置OAuth的代碼實(shí)踐

    在進(jìn)行Java后端技術(shù)框架版本升級(jí)時(shí),特別是將SpringBoot從2.X升級(jí)到3.X,發(fā)現(xiàn)對(duì)OAuth的配置有大幅變更,新版本中刪除了多個(gè)常用配置類(lèi),本文給大家介紹SpringBoot3.X配置OAuth的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2024-09-09
  • springboot2.0如何通過(guò)fastdfs實(shí)現(xiàn)文件分布式上傳

    springboot2.0如何通過(guò)fastdfs實(shí)現(xiàn)文件分布式上傳

    這篇文章主要介紹了springboot2.0如何通過(guò)fastdfs實(shí)現(xiàn)文件分布式上傳,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • java實(shí)現(xiàn)簡(jiǎn)單圖片上傳下載功能

    java實(shí)現(xiàn)簡(jiǎn)單圖片上傳下載功能

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡(jiǎn)單圖片上傳下載功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • Java程序運(yùn)行之JDK,指令javac java解讀

    Java程序運(yùn)行之JDK,指令javac java解讀

    這篇文章主要介紹了Java程序運(yùn)行之JDK,指令javac java,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01

最新評(píng)論

宜川县| 诸暨市| 舒城县| 青冈县| 秦安县| 宁远县| 泗洪县| 沭阳县| 杭锦旗| 宕昌县| 沽源县| 仁怀市| 巴东县| 荥阳市| 临清市| 上杭县| 德化县| 赤峰市| 轮台县| 宁强县| 会昌县| 阿尔山市| 富平县| 临夏市| 云梦县| 太仓市| 惠东县| 黔东| 富阳市| 汝南县| 银川市| 嵊泗县| 玉溪市| 新宾| 龙川县| 南丰县| 蒙自县| 旅游| 晋中市| 屯留县| 万山特区|