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

Springboot?配置線程池創(chuàng)建線程及配置?@Async?異步操作線程池詳解

 更新時(shí)間:2022年09月21日 15:33:03   作者:繁華盡頭滿是殤  
這篇文章主要介紹了Springboot?配置線程池創(chuàng)建線程及配置?@Async?異步操作線程池詳解,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下

前言

眾所周知,創(chuàng)建顯示線程和直接使用未配置的線程池創(chuàng)建線程,都會(huì)被阿里的大佬給diss,所以我們要規(guī)范的創(chuàng)建線程。

至于 @Async 異步任務(wù)的用處是不想等待方法執(zhí)行完就返回結(jié)果,提高軟件前臺(tái)響應(yīng)速度,一個(gè)程序中會(huì)用到很多異步方法,所以需要使用線程池管理,防止影響性能。

一、創(chuàng)建一個(gè)Springboot Web項(xiàng)目

需要一個(gè)Springboot項(xiàng)目

二、新建ThreadPoolConfig

  • 可以直接return一個(gè)內(nèi)置線程池
  • Executors類創(chuàng)建線程池的方法歸根結(jié)底都是調(diào)用ThreadPoolExecutor類,只不過對(duì)每個(gè)方法賦值不同的參數(shù)去構(gòu)造ThreadPoolExecutor對(duì)象。
  • newCachedThreadPool:創(chuàng)建一個(gè)可緩存的線程池,如果線程池長(zhǎng)度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程。
  •  newFixedThreadPool: 創(chuàng)建一個(gè)定長(zhǎng)線程池,可控制線程最大并發(fā)數(shù),超出的線程會(huì)在隊(duì)列中等待
  •  newScheduledThreadPool: 創(chuàng)建一個(gè)定長(zhǎng)線程池,支持定時(shí)及周期性任務(wù)執(zhí)行。
  • newSingleThreadExecutor: 創(chuàng)建一個(gè)單線程化的線程池,它只會(huì)用唯一的工作線程來執(zhí)行任務(wù),保證所有任務(wù)按照指定順序(FIFO, LIFO, 優(yōu)先級(jí))執(zhí)行。

也可以自己new一個(gè)ThreadPoolExecutor自定義參數(shù)

參數(shù)說明:

  •  corePoolSize: 常駐核心線程數(shù),如果大于0,即使本地任務(wù)執(zhí)行完也不會(huì)被銷毀
  •  maximumPoolSize: 線程池能夠容納可同時(shí)執(zhí)行的最大線程數(shù)
  •  keepAliveTime: 線程池中線程空閑的時(shí)間,當(dāng)空閑時(shí)間達(dá)到該值時(shí),線程會(huì)被銷毀, 只剩下 corePoolSize 個(gè)線程數(shù)量。
  • unit: 空閑時(shí)間的單位。一般以TimeUnit類定義時(shí)分秒。
  •  workQueue: 當(dāng)請(qǐng)求的線程數(shù)大于 corePoolSize 時(shí),線程進(jìn)入該阻塞隊(duì)列。
  •  threadFactory: 線程工廠,用來生產(chǎn)一組相同任務(wù)的線程,同時(shí)也可以通過它增加前綴名,虛擬機(jī)棧分析時(shí)更清晰
  •  handler: 執(zhí)行拒絕策略,當(dāng) workQueue 已滿,且超過maximumPoolSize 最大值,就要通過這個(gè)來處理,比如拒絕,丟棄等,這是一種限流的保護(hù)措施。

阻塞隊(duì)列的實(shí)現(xiàn)類:

  •  LinkedBlockingQueue 無界隊(duì)列,當(dāng)不指定隊(duì)列大小時(shí),將會(huì)默認(rèn)為Integer.MAX_VALUE大小的隊(duì)列,因此大量的任務(wù)將會(huì)堆積在隊(duì)列中,最終可能觸發(fā)OOM。
  •  ArrayBlockingQueue 有界隊(duì)列,基于數(shù)組的先進(jìn)先出隊(duì)列,此隊(duì)列創(chuàng)建時(shí)必須指定大小。
  •  PriorityBlockingQueue 有界隊(duì)列,基于優(yōu)先級(jí)任務(wù)的,它是通過Comparator決定的。
  •  SynchronousQueue 這個(gè)隊(duì)列比較特殊,它不會(huì)保存提交的任務(wù),而是將直接新建一個(gè)線程來執(zhí)行新來的任務(wù)

 處理策略Handler:

  •  AbortPolicy 默認(rèn)的拒絕策略,拋RejectedExecutionException異常
  •  DiscardPolicy 相當(dāng)大膽的策略,直接丟棄任務(wù),沒有任何異常拋出
  • DiscardOldestPolicy 丟棄最老的任務(wù),其實(shí)就是把最早進(jìn)入工作隊(duì)列的任務(wù)丟棄,然后把新任務(wù)加入到工作隊(duì)列
  •  CallerRunsPolicy 提交任務(wù)的線程自己去執(zhí)行該任務(wù)

線程池的關(guān)閉:

 shutdown() : 不會(huì)立刻終止線程,等所有緩存隊(duì)列中的任務(wù)都執(zhí)行完畢后才會(huì)終止。
shutdownNow() : 立即終止線程池,并嘗試打斷正在執(zhí)行的任務(wù),并且清空任務(wù)緩存隊(duì)列,返回尚未執(zhí)行的任務(wù)

package com.xuyijie.threadpooldemo.config;

import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.*;

/**
 * @author 徐一杰
 * @date 2022/9/20 13:05
 * @description 配置線程池
 */
@SpringBootConfiguration
@EnableAsync
public class ThreadPoolConfig {

    @Bean
    public ExecutorService getThreadPool(){
        ExecutorService threadPool = new ThreadPoolExecutor(2,5,
                1L, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());
        return threadPool;
//        return Executors.newCachedThreadPool();
    }

    /**
     * 下面的配置是配置Springboot的@Async注解所用的線程池
     */
    @Bean
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //獲取到cpu內(nèi)核數(shù)
        int i = Runtime.getRuntime().availableProcessors();
        // 設(shè)置線程池核心容量
        executor.setCorePoolSize(i);
        // 設(shè)置線程池最大容量
        executor.setMaxPoolSize(i * 2);
        // 設(shè)置任務(wù)隊(duì)列長(zhǎng)度
        executor.setQueueCapacity(200);
        // 設(shè)置線程超時(shí)時(shí)間
        executor.setKeepAliveSeconds(60);
        // 設(shè)置線程名稱前綴
        executor.setThreadNamePrefix("xyjAsyncPool-");
        // 設(shè)置任務(wù)丟棄后的處理策略,當(dāng)poolSize已達(dá)到maxPoolSize,如何處理新任務(wù)(是拒絕還是交由其它線程處理),CallerRunsPolicy:不在新線程中執(zhí)行任務(wù),而是由調(diào)用者所在的線程來執(zhí)
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }

}

使用此線程池時(shí)直接注入ExecutorService,然后:

executorService.execute(() -> {
?try {
String message = redisUtil.listRightPop(“queue:queueData”, 5, TimeUnit.SECONDS);
System.out.println(“接收到了消息message” + message);
} catch (Exception ex) {
date.set(simpleDateFormat.format(new Date()));
System.out.println(“隊(duì)列阻塞超時(shí)-” + date + ex.getMessage());
} finally {
?date.set(simpleDateFormat.format(new Date()));
System.out.println(“線程銷毀-” + date);
executorService.shutdown();
}
?});

三、新建controller測(cè)試

package com.xuyijie.threadpooldemo.controller;

import com.xuyijie.threadpooldemo.async.AsyncMethod;
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;

import java.util.concurrent.ExecutorService;

/**
 * @author 徐一杰
 * @date 2022/9/20 10:30
 * @description
 */
@RestController
@RequestMapping("/test")
public class TestController {

    @Autowired
    private ExecutorService executorService;
    @Autowired
    private AsyncMethod asyncMethod;
    
    @GetMapping("/helloThread")
    public void helloThread(){
        executorService.execute(() -> {
            for (int i = 0;i < 100;i++){
                System.out.println("111");
            }
        });
        executorService.execute(() -> {
            for (int i = 0;i < 100;i++){
                System.out.println("222");
            }
        });
    }
	
	@GetMapping("/helloAsync")
    public String helloAsync(){
    	// 這個(gè)方法是異步的
        asyncMethod.print();
        System.out.println("print方法還在循環(huán),但我已經(jīng)可以執(zhí)行了");
        return "print方法還在循環(huán),但我已經(jīng)可以執(zhí)行了";
    }

}

AsyncMethod.java

package com.xuyijie.threadpooldemo.async;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

/**
 * @author 徐一杰
 * @date 2022/9/20 15:10
 * @description 異步方法
 */
@Component
public class AsyncMethod {

	/**
     * 異步方法,如果@Async加在類的上面,則整個(gè)類中的方法都是異步的
     */
    @Async
    public void print(){
        for (int i = 0;i < 100;i++){
            System.out.println(i);
        }
    }
}

四、演示結(jié)果

首先演示 helloThread 這個(gè)接口,創(chuàng)建了2個(gè)線程,發(fā)現(xiàn)他們并發(fā)執(zhí)行,成功

再演示 helloAsync 這個(gè)接口,發(fā)現(xiàn) System.out.println("print方法還在循環(huán),但我已經(jīng)可以執(zhí)行了");這行代碼無需等待上面AsyncMethod中的 print 方法執(zhí)行完畢,就可以開始執(zhí)行,說明 print 方法是異步的,而且我輸出的日志注意看,[xyjAsyncPool - ],我設(shè)置的線程池前綴,已經(jīng)生效了,成功

到此這篇關(guān)于Springboot 配置線程池創(chuàng)建線程及配置 @Async 異步操作線程池詳解的文章就介紹到這了,更多相關(guān)Springboot 配置線程池 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 如何使用Mockito調(diào)用靜態(tài)方法和void方法

    如何使用Mockito調(diào)用靜態(tài)方法和void方法

    這篇文章主要介紹了如何使用Mockito調(diào)用靜態(tài)方法和void方法的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • iReport使用指南及常見功能示例詳解

    iReport使用指南及常見功能示例詳解

    這篇文章主要介紹了iReport使用指南及常見功能,本文以iReport 3.5.1為例,通過示例演示給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2021-10-10
  • 三種Java求最大值的方法

    三種Java求最大值的方法

    本篇文章給大家總結(jié)了在JAVA中求最大值的三種常用方法,以及代碼做了分享,需要的朋友參考下。
    2018-02-02
  • SpringBoot3.3.X整合Mybatis-Plus的實(shí)現(xiàn)示例

    SpringBoot3.3.X整合Mybatis-Plus的實(shí)現(xiàn)示例

    本文介紹了在Spring Boot 3.3.2中整合MyBatis-Plus 3.5.7,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-03-03
  • java之map集合存放null值的問題

    java之map集合存放null值的問題

    這篇文章主要介紹了java之map集合存放null值的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Java 八種基本類型和基本類型封裝類

    Java 八種基本類型和基本類型封裝類

    八種基本數(shù)據(jù)類型分別是:int、short、float、double、long、boolean、byte、char;下面跟隨腳本之家小編一起學(xué)習(xí)java八種基本類型和基本類型封裝類
    2017-09-09
  • SpringCloud學(xué)習(xí)筆記之OpenFeign進(jìn)行服務(wù)調(diào)用

    SpringCloud學(xué)習(xí)筆記之OpenFeign進(jìn)行服務(wù)調(diào)用

    OpenFeign對(duì)feign進(jìn)行進(jìn)一步的封裝,添加了springmvc的一些功能,更加強(qiáng)大,下面這篇文章主要給大家介紹了關(guān)于SpringCloud學(xué)習(xí)筆記之OpenFeign進(jìn)行服務(wù)調(diào)用的相關(guān)資料,需要的朋友可以參考下
    2022-01-01
  • Maven一鍵部署Springboot到Docker倉庫為自動(dòng)化做準(zhǔn)備(推薦)

    Maven一鍵部署Springboot到Docker倉庫為自動(dòng)化做準(zhǔn)備(推薦)

    這篇文章主要介紹了Maven一鍵部署Springboot到Docker倉庫,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Springboot整合logback的詳細(xì)教程

    Springboot整合logback的詳細(xì)教程

    這篇文章主要介紹了Springboot整合logback的相關(guān)知識(shí),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2024-01-01
  • Java容器類源碼詳解 Deque與ArrayDeque

    Java容器類源碼詳解 Deque與ArrayDeque

    這篇文章主要介紹了Java容器類源碼詳解 Deque與ArrayDeque,Deque 接口繼承自 Queue接口,但 Deque 支持同時(shí)從兩端添加或移除元素,因此又被成為雙端隊(duì)列。,需要的朋友可以參考下
    2019-06-06

最新評(píng)論

嘉定区| 拉萨市| 乌兰察布市| 会理县| 旌德县| 堆龙德庆县| 邯郸市| 海盐县| 剑河县| 左云县| 宜兰市| 迁安市| 海兴县| 新乐市| 石嘴山市| 唐海县| 阿克苏市| 盘锦市| 甘孜| 法库县| 晋州市| 南木林县| 辽源市| 新竹县| 揭阳市| 兖州市| 济宁市| 黑河市| 潼关县| 宣汉县| 德兴市| 奇台县| 乐至县| 孝义市| 兰西县| 亚东县| 万源市| 乌拉特中旗| 孙吴县| 竹溪县| 吉木萨尔县|