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

SpringBoot異步Async使用Future與CompletableFuture區(qū)別小結(jié)

 更新時(shí)間:2023年06月09日 09:51:46   作者:可樂漢堡cola  
本文主要介紹了SpringBoot異步Async使用Future與CompletableFuture區(qū)別小結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

主要區(qū)別:

  • Future:在執(zhí)行結(jié)束后沒法回調(diào),調(diào)用get方法會(huì)被阻塞;
  • CompletableFuture:在執(zhí)行結(jié)束后可通過whenComplete或whenCompleteAsync方法回調(diào),不會(huì)阻塞線程,同時(shí)也是支持get方法的;

代碼示例

spring boot配置Async,@EnableAsync啟動(dòng)異步

AsyncConfig

package com.test.config;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@EnableAsync
@Configuration
public class AsyncConfig {
    /**
     * 異步任務(wù)自定義線程池
     */
    @Bean(name="taskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(50);
        executor.setMaxPoolSize(500);
        executor.setQueueCapacity(300);
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("自定義線程-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAwaitTerminationSeconds(60);
        return executor;
    }
}

1.Future測(cè)試:

主線程等待各個(gè)異步執(zhí)行的線程返回的結(jié)果來做下一步操作,則必須阻塞在future.get()的地方等待結(jié)果返回,這時(shí)候又變成同步了。適用于需要等異步結(jié)果的場(chǎng)景。

FutureService

package com.test.service;
import java.util.concurrent.Future;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
@Service
public class FutureService {
    @Async
    public Future<String> futureTest1(){
        System.out.println(Thread.currentThread().getName()+"進(jìn)行任務(wù)futureTest1...");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"任務(wù)futureTest1完成");
        return new AsyncResult<String>("這是任務(wù)futureTest1返回結(jié)果");
    }
    @Async
    public Future<String> futureTest2(){
        System.out.println(Thread.currentThread().getName()+"進(jìn)行任務(wù)futureTest2...");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"任務(wù)futureTest2完成");
        return new AsyncResult<String>("這是任務(wù)futureTest2返回結(jié)果");
    }
}

FutureController

package com.test.controller;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.test.service.FutureService;
@RestController
@RequestMapping("/future")
public class FutureController {
    @Autowired
    private FutureService futureService;
    //超時(shí)時(shí)間
      public static final long timeout = 30;
    @RequestMapping(value = "futureTest", method = RequestMethod.GET)
    public String futureTest() {
        // 開始時(shí)間戳
        long beginTime = System.currentTimeMillis();
        Future<String> result1 = futureService.futureTest1();
        Future<String> result2 = futureService.futureTest2();
        //添加結(jié)果集,30秒超時(shí)
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            String str1 = result1.get(timeout, TimeUnit.SECONDS);
            System.out.println(str1);
            String str2 = result2.get(timeout, TimeUnit.SECONDS);
            System.out.println(str2);
            map.put("result1", str1);
            map.put("result2", str2);
            //這里需要等get()完成后才會(huì)執(zhí)行,因?yàn)間et()方法會(huì)阻塞
            System.out.println("map集合: "+map.size());
            System.out.println("回調(diào)后的任務(wù): "+Thread.currentThread().getName());
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("耗時(shí): "+(System.currentTimeMillis() - beginTime));
        return "success";
    }
}

 打印結(jié)果

自定義線程-1進(jìn)行任務(wù)futureTest1...
自定義線程-2進(jìn)行任務(wù)futureTest2...
自定義線程-1任務(wù)futureTest1完成
這是任務(wù)futureTest1返回結(jié)果
自定義線程-2任務(wù)futureTest2完成
這是任務(wù)futureTest2返回結(jié)果
map集合: 2
回調(diào)后的任務(wù): http-nio-8082-exec-1
耗時(shí): 5068

大家可以看到,這時(shí)候map集合里面是有值的,主線程http-nio-8082-exec-1是在異步執(zhí)行完才執(zhí)行的,因?yàn)間et方法是會(huì)阻塞線程的。耗時(shí)5秒是以異步中耗時(shí)最長(zhǎng)的方法為準(zhǔn),因?yàn)橐群臅r(shí)最長(zhǎng)的方法執(zhí)行完,才能合并。

2.CompletableFuture測(cè)試:

實(shí)現(xiàn)了Future和CompletionStage接口,保留了Future的優(yōu)點(diǎn),并且彌補(bǔ)了其不足。即異步的任務(wù)完成后,需要用其結(jié)果繼續(xù)操作時(shí),無需等待。適用于不需要等異步結(jié)果的場(chǎng)景。

CompletableFutureService

package com.test.service;
import java.util.concurrent.CompletableFuture;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class CompletableFutureService {
    @Async
    public CompletableFuture<String> completableFuture1(){
        System.out.println(Thread.currentThread().getName()+"進(jìn)行任務(wù)completableFuture1...");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"任務(wù)completableFuture1完成");
        return CompletableFuture.completedFuture("這是任務(wù)completableFuture1返回結(jié)果");
    }
    @Async
    public CompletableFuture<String> completableFuture2(){
        System.out.println(Thread.currentThread().getName()+"進(jìn)行任務(wù)completableFuture2...");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"任務(wù)completableFuture2完成");
        return CompletableFuture.completedFuture("這是任務(wù)completableFuture2返回結(jié)果");
    }
}

CompletableFutureController

package com.test.controller;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.test.service.CompletableFutureService;
@RestController
@RequestMapping("/completable")
public class CompletableFutureController {
    @Autowired
    private CompletableFutureService completableFutureService;
    @RequestMapping(value = "completableFutureTest", method = RequestMethod.GET)
    public String CompletableFutureTest() {
        // 開始時(shí)間戳
        long beginTime = System.currentTimeMillis();
        CompletableFuture<String> result1 = completableFutureService.completableFuture1();
        CompletableFuture<String> result2 = completableFutureService.completableFuture2();
        //添加結(jié)果集,30秒超時(shí)
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            result1.whenComplete((r, t)->{
                System.out.println(r+Thread.currentThread().getName());
                map.put("result1", r);
            });
            result2.whenComplete((r, t)->{
                System.out.println(r+Thread.currentThread().getName());
                map.put("result2", r);
            });
            //這里不用等前面的結(jié)果集,會(huì)異步先執(zhí)行
            System.out.println("map集合: "+map.size());
            System.out.println("回調(diào)后的任務(wù): "+Thread.currentThread().getName());
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("耗時(shí): "+(System.currentTimeMillis() - beginTime));
        return "success";
    }
}

打印結(jié)果

map集合: 0
回調(diào)后的任務(wù): http-nio-8082-exec-1
耗時(shí): 33
自定義線程-1進(jìn)行任務(wù)completableFuture1...
自定義線程-2進(jìn)行任務(wù)completableFuture2...
自定義線程-1任務(wù)completableFuture1完成
這是任務(wù)completableFuture1返回結(jié)果自定義線程-1
自定義線程-2任務(wù)completableFuture2完成
這是任務(wù)completableFuture2返回結(jié)果自定義線程-2

大家可以看到,這時(shí)候map集合里面是空的,主線程http-nio-8082-exec-1是在異步之前打印的,說明使用whenComplete是異步的,不會(huì)阻塞線程的。耗時(shí)33毫秒不用等異步執(zhí)行完就能打印。

這里簡(jiǎn)單說下whenComplete和whenCompleteAsync的區(qū)別:

whenComplete:執(zhí)行完當(dāng)前任務(wù)的線程,繼續(xù)執(zhí)行 whenComplete 的任務(wù)。
whenCompleteAsync: 執(zhí)行完當(dāng)前任務(wù)的線程,把whenCompleteAsync 的任務(wù)繼續(xù)提交給線程池來執(zhí)行。(可能開啟新的線程)

把前面的改成whenCompleteAsync測(cè)試一下

result1.whenCompleteAsync((r, t)->{
                System.out.println(r+Thread.currentThread().getName());
                map.put("result1", r);
            });
            result2.whenCompleteAsync((r, t)->{
                System.out.println(r+Thread.currentThread().getName());
                map.put("result2", r);
            });

打印結(jié)果

map集合: 0
回調(diào)后的任務(wù): http-nio-8082-exec-1
耗時(shí): 33
自定義線程-1進(jìn)行任務(wù)completableFuture1...
自定義線程-2進(jìn)行任務(wù)completableFuture2...
自定義線程-1任務(wù)completableFuture1完成
這是任務(wù)completableFuture1返回結(jié)果Thread-4
自定義線程-2任務(wù)completableFuture2完成
這是任務(wù)completableFuture2返回結(jié)果Thread-5

區(qū)別的地方在于Thread-4和Thread-5,這是新開的線程,不是線程池中的線程了。

總結(jié):

Future與CompletableFuture使用場(chǎng)景不一樣,都支持get方法,如果異步執(zhí)行完后需要同步,使用Future,反之,如果異步執(zhí)行完后,不需要等待,直接異步操作,那么使用CompletableFuture。

到此這篇關(guān)于SpringBoot異步Async使用Future與CompletableFuture區(qū)別小結(jié)的文章就介紹到這了,更多相關(guān)SpringBoot Future CompletableFuture內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 將Mybatis升級(jí)為Mybatis-Plus的詳細(xì)過程

    將Mybatis升級(jí)為Mybatis-Plus的詳細(xì)過程

    本文詳細(xì)介紹了在若依管理系統(tǒng)(v3.8.8)中將MyBatis升級(jí)為MyBatis-Plus的過程,旨在提升開發(fā)效率,通過本文,開發(fā)者可實(shí)現(xiàn)系統(tǒng)功能無損升級(jí),同時(shí)享受MyBatis-Plus帶來的便捷特性,如代碼簡(jiǎn)化和性能優(yōu)化,需要的朋友可以參考下
    2025-04-04
  • Java中extends一定是代表繼承嗎?

    Java中extends一定是代表繼承嗎?

    今天小編就為大家分享一篇關(guān)于Java中extends一定是代表繼承嗎?,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • 基于Spring p標(biāo)簽和c標(biāo)簽注入方式

    基于Spring p標(biāo)簽和c標(biāo)簽注入方式

    這篇文章主要介紹了Spring p標(biāo)簽和c標(biāo)簽注入方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • 如何使用Bean Validation 解決業(yè)務(wù)中參數(shù)校驗(yàn)

    如何使用Bean Validation 解決業(yè)務(wù)中參數(shù)校驗(yàn)

    這篇文章主要介紹了如何使用Bean Validation 解決業(yè)務(wù)中參數(shù)校驗(yàn)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • idea如何保存當(dāng)前已修改的文件|恢復(fù)到未修改狀態(tài)

    idea如何保存當(dāng)前已修改的文件|恢復(fù)到未修改狀態(tài)

    文章主要介紹了如何在Git中將修改暫存起來以及如何恢復(fù)這些暫存的修改,詳細(xì)步驟包括提交修改、保存修改、查看和恢復(fù)修改等過程
    2026-04-04
  • Java語法基礎(chǔ)之選擇結(jié)構(gòu)的if語句、switch語句詳解

    Java語法基礎(chǔ)之選擇結(jié)構(gòu)的if語句、switch語句詳解

    這篇文章主要為大詳細(xì)介紹了Java語法基礎(chǔ)之選擇結(jié)構(gòu)的if語句、switch語句,感興趣的小伙伴們可以參考一下
    2016-09-09
  • 利用java監(jiān)聽器實(shí)現(xiàn)在線人數(shù)統(tǒng)計(jì)

    利用java監(jiān)聽器實(shí)現(xiàn)在線人數(shù)統(tǒng)計(jì)

    過去使用ASP和ASP.NET兩種編程的時(shí)候,都寫過在線人數(shù)統(tǒng)計(jì)能,實(shí)現(xiàn)功能挺簡(jiǎn)單的!今天使用java來實(shí)現(xiàn)在線人數(shù)統(tǒng)計(jì)有點(diǎn)另類,是通過Java監(jiān)聽器實(shí)現(xiàn)的,需要的朋友可以參考下
    2015-09-09
  • 詳解eclipse中Maven工程使用Tomcat7以上插件的方法

    詳解eclipse中Maven工程使用Tomcat7以上插件的方法

    本篇文章主要介紹了詳解eclipse中Maven工程使用Tomcat7以上插件的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-12-12
  • 淺談對(duì)java中鎖的理解

    淺談對(duì)java中鎖的理解

    本文主要講述java中鎖的相關(guān)知識(shí)。具有很好的參考價(jià)值,下面跟著小編一起來看下吧
    2017-03-03
  • SpringBoot XSS攻擊的常見形式與防范方法

    SpringBoot XSS攻擊的常見形式與防范方法

    XSS攻擊是指攻擊者在Web頁(yè)面的輸入數(shù)據(jù)中插入惡意腳本,當(dāng)其他用戶瀏覽該頁(yè)面時(shí),這些腳本就會(huì)在用戶的瀏覽器上執(zhí)行,可能導(dǎo)致信息泄露、會(huì)話劫持、惡意操作等安全風(fēng)險(xiǎn),本文給大家介紹了SpringBoot XSS攻擊的常見形式與防范方法,需要的朋友可以參考下
    2024-11-11

最新評(píng)論

广元市| 绥阳县| 博罗县| 宜春市| 宁城县| 西乡县| 长武县| 子洲县| 隆尧县| 大庆市| 绵竹市| 永州市| 蓬溪县| 灯塔市| 盈江县| 绥宁县| 汝州市| 乌兰察布市| 襄樊市| 泗洪县| 成都市| 资讯 | 大连市| 筠连县| 桐乡市| 德昌县| 琼结县| 施甸县| 鱼台县| 高雄县| 恩施市| 泰兴市| 韩城市| 铅山县| 鱼台县| 绥宁县| 乌鲁木齐县| 大厂| 南平市| 孟州市| 宁海县|