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

Spring使用ThreadPoolTaskExecutor自定義線程池及異步調用方式

 更新時間:2022年02月25日 14:30:25   作者:create17  
這篇文章主要介紹了Spring使用ThreadPoolTaskExecutor自定義線程池及異步調用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

多線程一直是工作或面試過程中的高頻知識點,今天給大家分享一下使用 ThreadPoolTaskExecutor 來自定義線程池和實現(xiàn)異步調用多線程。

一、ThreadPoolTaskExecutor

本文采用 Executors 的工廠方法進行配置。

1、將線程池用到的參數(shù)定義到配置文件中

在項目的 resources 目錄下創(chuàng)建 executor.properties 文件,并添加如下配置:

# 異步線程配置
# 核心線程數(shù)
async.executor.thread.core_pool_size=5
# 最大線程數(shù)
async.executor.thread.max_pool_size=8
# 任務隊列大小
async.executor.thread.queue_capacity=2
# 線程池中線程的名稱前綴
async.executor.thread.name.prefix=async-service-
# 緩沖隊列中線程的空閑時間
async.executor.thread.keep_alive_seconds=100

2、Executors 的工廠配置

2.1、配置詳情

@Configuration
// @PropertySource是找的target目錄下classes目錄下的文件,resources目錄下的文件編譯后會生成在classes目錄
@PropertySource(value = {"classpath:executor.properties"}, ignoreResourceNotFound=false, encoding="UTF-8")
@Slf4j
public class ExecutorConfig {
    @Value("${async.executor.thread.core_pool_size}")
    private int corePoolSize;
    @Value("${async.executor.thread.max_pool_size}")
    private int maxPoolSize;
    @Value("${async.executor.thread.queue_capacity}")
    private int queueCapacity;
    @Value("${async.executor.thread.name.prefix}")
    private String namePrefix;
    @Value("${async.executor.thread.keep_alive_seconds}")
    private int keepAliveSeconds;
    @Bean(name = "asyncTaskExecutor")
    public ThreadPoolTaskExecutor taskExecutor() {
        log.info("啟動");
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 核心線程數(shù)
        executor.setCorePoolSize(corePoolSize);
        // 最大線程數(shù)
        executor.setMaxPoolSize(maxPoolSize);
        // 任務隊列大小
        executor.setQueueCapacity(queueCapacity);
        // 線程前綴名
        executor.setThreadNamePrefix(namePrefix);
        // 線程的空閑時間
        executor.setKeepAliveSeconds(keepAliveSeconds);
        // 拒絕策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 線程初始化
        executor.initialize();
        return executor;
    }
}

2.2、注解說明

  • @Configuration:Spring 容器在啟動時,會加載帶有 @Configuration 注解的類,對其中帶有 @Bean 注解的方法進行處理。
  • @Bean:是一個方法級別上的注解,主要用在 @Configuration 注解的類里,也可以用在 @Component 注解的類里。添加的 bean 的 id 為方法名。
  • @PropertySource:加載指定的配置文件。value 值為要加載的配置文件,ignoreResourceNotFound 意思是如果加載的文件找不到,程序是否忽略它。默認為 false 。如果為 true ,則代表加載的配置文件不存在,程序不報錯。在實際項目開發(fā)中,最好設置為 false 。如果 application.properties 文件中的屬性與自定義配置文件中的屬性重復,則自定義配置文件中的屬性值被覆蓋,加載的是 application.properties 文件中的配置屬性。
  • @Slf4j:lombok 的日志輸出工具,加上此注解后,可直接調用 log 輸出各個級別的日志。
  • @Value:調用配置文件中的屬性并給屬性賦予值。

2.3、線程池配置說明

  • 核心線程數(shù):線程池創(chuàng)建時候初始化的線程數(shù)。當線程數(shù)超過核心線程數(shù),則超過的線程則進入任務隊列。
  • 最大線程數(shù):只有在任務隊列滿了之后才會申請超過核心線程數(shù)的線程。不能小于核心線程數(shù)。
  • 任務隊列:線程數(shù)大于核心線程數(shù)的部分進入任務隊列。如果任務隊列足夠大,超出核心線程數(shù)的線程不會被創(chuàng)建,它會等待核心線程執(zhí)行完它們自己的任務后再執(zhí)行任務隊列的任務,而不會再額外地創(chuàng)建線程。舉例:如果有20個任務要執(zhí)行,核心線程數(shù):10,最大線程數(shù):20,任務隊列大小:2。則系統(tǒng)會創(chuàng)建18個線程。這18個線程有執(zhí)行完任務的,再執(zhí)行任務隊列中的任務。
  • 線程的空閑時間:當 線程池中的線程數(shù)量 大于 核心線程數(shù) 時,如果某線程空閑時間超過 keepAliveTime ,線程將被終止。這樣,線程池可以動態(tài)的調整池中的線程數(shù)。
  • 拒絕策略:如果(總任務數(shù) - 核心線程數(shù) - 任務隊列數(shù))-(最大線程數(shù) - 核心線程數(shù))> 0 的話,則會出現(xiàn)線程拒絕。舉例:( 12 - 5 - 2 ) - ( 8 - 5 ) > 0,會出現(xiàn)線程拒絕。線程拒絕又分為 4 種策略,分別為:
  • CallerRunsPolicy():交由調用方線程運行,比如 main 線程。
  • AbortPolicy():直接拋出異常。
  • DiscardPolicy():直接丟棄。
  • DiscardOldestPolicy():丟棄隊列中最老的任務。

2.4、線程池配置個人理解

  • 當一個任務被提交到線程池時,首先查看線程池的核心線程是否都在執(zhí)行任務。如果沒有,則選擇一條線程執(zhí)行任務。
  • 如果都在執(zhí)行任務,查看任務隊列是否已滿。如果不滿,則將任務存儲在任務隊列中。核心線程執(zhí)行完自己的任務后,會再處理任務隊列中的任務。
  • 如果任務隊列已滿,查看線程池(最大線程數(shù)控制)是否已滿。如果不滿,則創(chuàng)建一條線程去執(zhí)行任務。如果滿了,就按照策略處理無法執(zhí)行的任務。

二、異步調用線程

通常 ThreadPoolTaskExecutor 是和 @Async 一起使用。在一個方法上添加 @Async 注解,表明是異步調用方法函數(shù)。

@Async 后面加上線程池的方法名或 bean 名稱,表明異步線程會加載線程池的配置。

@Component
@Slf4j
public class ThreadTest {
    /**
     * 每10秒循環(huán)一次,一個線程共循環(huán)10次。
     */
    @Async("asyncTaskExecutor")
    public void ceshi3() {
        for (int i = 0; i <= 10; i  ) {
            log.info("ceshi3: "   i);
            try {
                Thread.sleep(2000 * 5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

備注:一定要在啟動類上添加 @EnableAsync 注解,這樣 @Async 注解才會生效。

三、多線程使用場景

1、定時任務 @Scheduled

// 在啟動類上添加 @EnableScheduling 注解
@SpringBootApplication
@EnableScheduling
public class SpringBootStudyApplication {
? ?public static void main(String[] args) {
? ? ? SpringApplication.run(SpringBootStudyApplication.class, args);
? ?}
}
// @Component 注解將定時任務類納入 spring bean 管理。
@Component
public class listennerTest3 {
? ? @Autowired
? ? private ThreadTest t;
? ??
? ? // 每1分鐘執(zhí)行一次ceshi3()方法
? ? @Scheduled(cron = "0 0/1 * * * ?")
? ? public void run() {
? ? ? ? t.ceshi3();
? ? }
}

ceshi3() 方法調用線程池配置,且異步執(zhí)行。

@Component
@Slf4j
public class ThreadTest {
? ? /**
? ? ?* 每10秒循環(huán)一次,一個線程共循環(huán)10次。
? ? ?*/
? ? @Async("asyncTaskExecutor")
? ? public void ceshi3() {
? ? ? ? for (int i = 0; i <= 10; i ?) {
? ? ? ? ? ? log.info("ceshi3: " ? i);
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? Thread.sleep(2000 * 5);
? ? ? ? ? ? } catch (InterruptedException e) {
? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? }
? ? ? ? }
? ? }
}

2、程序一啟動就異步執(zhí)行多線程

通過繼承 CommandLineRunner 類實現(xiàn)。

@Component
public class ListennerTest implements CommandLineRunner {
? ? @Autowired
? ? private ThreadTest t;
? ? @Override
? ? public void run(String... args) {
? ? ? ? for (int i = 1; i <= 10; i ?) {
? ? ? ? ? ? t.ceshi();
? ? ? ? }
? ? }
}
@Component
@Slf4j
public class ThreadTest {
? ? @Async("asyncTaskExecutor")
? ? public void ceshi() {
? ? ? ? log.info("ceshi");
? ? }
} ? ?

3、定義一個 http 接口

還可以通過接口的形式來異步調用多線程:

@RestController
@RequestMapping("thread")
public class ListennerTest2 {
? ? @Autowired
? ? private ThreadTest t;
? ? @GetMapping("ceshi2")
? ? public void run() {
? ? ? ? for (int i = 1; i < 10; i ?) {
? ? ? ? ? ? t.ceshi2();
? ? ? ? }
? ? }
}
@Component
@Slf4j
public class ThreadTest {
? ? @Async("asyncTaskExecutor")
? ? public void ceshi2() {
? ? ? ? for (int i = 0; i <= 3; i ?) {
? ? ? ? ? ? log.info("ceshi2");
? ? ? ? }
? ? }
} ? ?

4、測試類

@RunWith(SpringRunner.class)
@SpringBootTest
public class ThreadRunTest {
? ? @Autowired
? ? private ThreadTest t;
? ? @Test
? ? public void thread1() {
? ? ? ? for (int i = 1; i <= 10; i ?) {
? ? ? ? ? ? t.ceshi4();
? ? ? ? }
? ? }
}
@Component
@Slf4j
public class ThreadTest {
? ? @Async("asyncTaskExecutor")
? ? public void ceshi4() {
? ? ? ? log.info("ceshi4");
? ? }
}

四、總結

以上主要介紹了 ThreadPoolTaskExecutor 線程池的配置、使用、相關注解的意義及作用,也簡單介紹了使用 @Async 來異步調用線程,最后又列舉了多線程的使用場景,并配上了代碼示例。這些僅為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • Java?Jar包項目內存設置方法舉例

    Java?Jar包項目內存設置方法舉例

    這篇文章主要給大家介紹了關于Java?Jar包項目內存設置方法的相關資料,文中通過代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2024-01-01
  • springboot整合RabbitMQ發(fā)送短信的實現(xiàn)

    springboot整合RabbitMQ發(fā)送短信的實現(xiàn)

    本文會和SpringBoot做整合,實現(xiàn)RabbitMQ發(fā)送短信,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-05-05
  • java、android可用的rtp封包解包h264案例

    java、android可用的rtp封包解包h264案例

    這篇文章主要介紹了java、android可用的rtp封包解包h264案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • Java導出Excel統(tǒng)計報表合并單元格的方法詳解

    Java導出Excel統(tǒng)計報表合并單元格的方法詳解

    我們在日常編程過程中,總是會碰見導出相關表格信息的需求,所以就讓我們一起來學習一下,這篇文章主要給大家介紹了關于Java導出Excel統(tǒng)計報表合并單元格的相關資料,需要的朋友可以參考下
    2021-10-10
  • Servlet關于RequestDispatcher的原理詳解

    Servlet關于RequestDispatcher的原理詳解

    這篇文章主要介紹了Servlet關于RequestDispatcher的原理詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11
  • Hibernate環(huán)境搭建與配置方法(Hello world配置文件版)

    Hibernate環(huán)境搭建與配置方法(Hello world配置文件版)

    這篇文章主要介紹了Hibernate環(huán)境搭建與配置方法,這里演示Hello world配置文件版的具體實現(xiàn)步驟與相關代碼,需要的朋友可以參考下
    2016-03-03
  • JVM內存區(qū)域劃分相關原理詳解

    JVM內存區(qū)域劃分相關原理詳解

    這篇文章主要介紹了JVM內存區(qū)域劃分相關原理詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-10-10
  • Java基于迭代器模式實現(xiàn)的訪問人員列表操作示例

    Java基于迭代器模式實現(xiàn)的訪問人員列表操作示例

    這篇文章主要介紹了Java基于迭代器模式實現(xiàn)的訪問人員列表操作,簡單描述了迭代器模式的概念、原理以及使用迭代器模式實現(xiàn)訪問人員列表的相關操作技巧,需要的朋友可以參考下
    2018-05-05
  • MyBatis生成UUID的實現(xiàn)

    MyBatis生成UUID的實現(xiàn)

    這篇文章主要介紹了MyBatis生成UUID的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • spring boot 枚舉使用的坑整理

    spring boot 枚舉使用的坑整理

    在本篇文章里我們給大家整理了關于spring boot 枚舉使用的坑以及相關知識點內容,需要的朋友們學習下。
    2019-08-08

最新評論