欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Springboot?@Async多線程獲取返回值方式

 更新時間:2023年09月27日 09:21:17   作者:小白Alan  
這篇文章主要介紹了Springboot?@Async多線程獲取返回值方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

@Async 多線程獲取返回值

最近需要用到多線程 自己維護線程池很麻煩 正好看到 springboot 集成線程池的例子 這里自己做了個嘗試和總結 記錄一下 也分享給需要的朋友;

不考慮事務的情況下 這個多線程實現(xiàn)比較簡單 

主要有以下幾點

  • 在啟動類加上  @EnableAsync 注解, 開啟異步執(zhí)行支持;
  • 編寫線程池配置類, 別忘了 @Configuration , 和 @Bean 注解;
  • 編寫需要異步執(zhí)行的業(yè)務, 放到單獨的類中 (可以定義為 service, 因為需要 spring 管理起來才能用 );
  • 在業(yè)務service中調用異步執(zhí)行的service, 注意這是重點, 不能直接在業(yè)務 service 中寫異步執(zhí)行的代碼, 否則無法異步執(zhí)行( 這就是單獨放異步代碼的原因);

好了, 上代碼:

// 啟動類
@EnableAsync
@EnableWebSecurity
@ServletComponentScan
@SpringBootApplication(scanBasePackages={"com.example.demo"})
public class DemoApplication {
	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}
}
// 線程池配置類
@Slf4j
@Configuration
public class BootThreadpoolConfig {
    // 配置核心線程數(shù)
    private int corePoolSize = 5;
    // 配置最大線程數(shù)
    private int maxPoolSize = 20;
    // 配置任務隊列的長度
    private int queueCapacity = 500;
    // 配置任務的空閑時間
    private int aliveSeconds = 600;
    // 配置線程前綴
    private String namePrefix = "localThreadPool";
    // 自定義線程池, 起個好記的名
    @Bean(name = "localBootAsyncExecutor")
    public Executor asyncServiceExecutor() {
        log.info("初始化 springboot 線程池");
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //配置核心線程數(shù)
        executor.setCorePoolSize(corePoolSize);
        //配置最大線程數(shù)
        executor.setMaxPoolSize(maxPoolSize);
        //配置隊列大小
        executor.setQueueCapacity(queueCapacity);
        //配置線程池中的線程的名稱前綴
        executor.setThreadNamePrefix(namePrefix);
        //配置線程的空閑時間
        executor.setKeepAliveSeconds(aliveSeconds);
        // RejectedExecutionHandler:當pool已經(jīng)達到max size的時候,如何處理新任務
        // CallerRunsPolicy:不在新線程中執(zhí)行任務,而是有調用者所在的線程來執(zhí)行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //執(zhí)行初始化
        executor.initialize();
        log.info("springboot 線程池初始化完畢");
        return executor;
    }
}
// 異步執(zhí)行代碼
@Service("asyncExecutorTest")
public class AsyncExecutorTest {
    // 異步執(zhí)行的方法, 注解內為自定義線程池類名
    @Async("localBootAsyncExecutor")
    public Future<Integer> test1(Integer i) throws InterruptedException {
        Thread.sleep(100);
        System.out.println("@Async 執(zhí)行: " + i);
        return new AsyncResult(i);
    }
    // 這里使用其它方式調用,詳見后面的 service3 方法
    public Integer test2(Integer i) throws InterruptedException {
        Thread.sleep(100);
        System.out.println(" excute.run 執(zhí)行: " + i);
        return i;
    }
}
// 業(yè)務 service
@Service("asyncExcutorService")
public class AsyncExcutorService {
    @Autowired
    AsyncExecutorTest asyncExecutorTest;
    @Autowired
    Executor localBootAsyncExecutor;
    // 測試 無返回值異步執(zhí)行
    public void service1(){
        System.out.println("service1 執(zhí)行----->");
        for (int i = 0; i < 50; i++) {
            try {
                asyncExecutorTest.test1(i);
            } catch (InterruptedException e) {
                System.out.println("service1執(zhí)行出錯");
            }
        }
        System.out.println("service1 結束----->");
    }
    // 測試 有返回值異步執(zhí)行
    public void service2(){
        long l = System.currentTimeMillis();
        System.out.println("service2 執(zhí)行----->");
        List<Future> result = new ArrayList<>();
        try {
            for (int i = 0; i < 300; i++) {
                Future<Integer> integerFuture = asyncExecutorTest.test1(i);
                result.add(integerFuture);
            }
            for (Future future : result) {
                System.out.println(future.get());
            }
        } catch (InterruptedException | ExecutionException e) {
            System.out.println("service2執(zhí)行出錯");
        }
        System.out.println("service2 結束----->" + (System.currentTimeMillis() - l));
    }
    // 測試 有返回值異步執(zhí)行
    public void service3(){
        long l = System.currentTimeMillis();
        List<Integer> result = new ArrayList<>();
        try {
            System.out.println("service3 執(zhí)行----->");
            int total = 300;
            CountDownLatch latch = new CountDownLatch(total);
            for (int i = 0; i < total; i++) {
                final int y = i;
                localBootAsyncExecutor.execute(() -> {
                    try {
                        result.add(asyncExecutorTest.test2(y));
                    } catch (InterruptedException e) {
                        System.out.println("service3執(zhí)行出錯");
                    } finally {
                        latch.countDown();
                    }
                });
            }
            latch.await();
        } catch (InterruptedException e) {
            System.out.println("service3執(zhí)行出錯");
        }
        System.out.println("service3 結束----->" + (System.currentTimeMillis() - l));
    }
}

這里說下service1 和 service2的區(qū)別

1. 兩個都用的是一個線程池執(zhí)行的

2. service1 單純執(zhí)行業(yè)務, 不用返回數(shù)據(jù), 主線程也不用等待

3. service2 需要返回數(shù)據(jù), 主線程需要等待結果( 注意返回值只能是 Future, 最后再 .get()去獲取, 否則無法異步執(zhí)行)

4. service3 也可以返回數(shù)據(jù), 但是書寫上麻煩一些.  返回值直接是想要的結果, 不像 service2 還需要提取一次數(shù)據(jù).

其它就是 controller 了, 自己隨便寫一個調用一下就行了, 這里就不寫了, 以下是我測試的 console 日志

  • service1 執(zhí)行日志

  • service2 執(zhí)行日志

  • service3

總結

打完收工!

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • java list集合排序按某一屬性排序操作

    java list集合排序按某一屬性排序操作

    這篇文章主要介紹了java list集合排序按某一屬性排序操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • Spring Cloud引入Eureka組件,完善服務治理

    Spring Cloud引入Eureka組件,完善服務治理

    這篇文章主要介紹了Spring Cloud引入Eureka組件,完善服務治理的過程詳解,幫助大家更好的理解和使用spring cloud,感興趣的朋友可以了解下
    2021-02-02
  • java實現(xiàn)獲取安卓設備里已安裝的軟件包

    java實現(xiàn)獲取安卓設備里已安裝的軟件包

    本文給大家介紹的是如何獲取設備中已經(jīng)安裝的應用軟件包的代碼,其核心方法原理很簡單,我們通過Android中提供的PackageManager類,來獲取手機中安裝的應用程序信息
    2015-10-10
  • JAVA的Dubbo如何實現(xiàn)各種限流算法

    JAVA的Dubbo如何實現(xiàn)各種限流算法

    Dubbo是一種高性能的Java RPC框架,廣泛應用于分布式服務架構中,在Dubbo中實現(xiàn)限流可以幫助服務在高并發(fā)場景下保持穩(wěn)定性和可靠性,常見的限流算法包括固定窗口算法、滑動窗口算法、令牌桶算法和漏桶算法,在Dubbo中集成限流器可以通過實現(xiàn)自定義過濾器來實現(xiàn)
    2025-01-01
  • 基于Java回顧之多線程詳解

    基于Java回顧之多線程詳解

    在這篇文章里,我們關注多線程。多線程是一個復雜的話題,包含了很多內容,這篇文章主要關注線程的基本屬性、如何創(chuàng)建線程、線程的狀態(tài)切換以及線程通信,我們把線程同步的話題留到下一篇文章中
    2013-05-05
  • 在mybatis中去除多余的前綴或者后綴操作

    在mybatis中去除多余的前綴或者后綴操作

    這篇文章主要介紹了在mybatis中去除多余的前綴或者后綴操作。具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • btrace定位生產(chǎn)故障的方法示例

    btrace定位生產(chǎn)故障的方法示例

    這篇文章主要介紹了btrace定位生產(chǎn)故障的方法示例,文中通過示例代碼介紹的很詳細,相信對大家具有一定的參考價值,需要的朋友們下面來一起看看吧。
    2017-02-02
  • java中關于getProperties方法的使用

    java中關于getProperties方法的使用

    這篇文章主要介紹了java中關于getProperties方法的使用,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Java 比較接口comparable與comparator區(qū)別解析

    Java 比較接口comparable與comparator區(qū)別解析

    這篇文章主要介紹了Java 比較接口comparable與comparator區(qū)別解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-10-10
  • 解決springboot+thymeleaf視圖映射報錯There?was?an?unexpected?error?(type=Not?Found,?status=404)

    解決springboot+thymeleaf視圖映射報錯There?was?an?unexpected?erro

    這篇文章主要介紹了解決springboot+thymeleaf視圖映射報錯There?was?an?unexpected?error?(type=Not?Found,?status=404)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12

最新評論