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

SpringBoot配置線程池的實現(xiàn)示例

 更新時間:2023年09月22日 15:48:47   作者:何不語i  
本文主要介紹了SpringBoot配置線程池的實現(xiàn)示例,主要包括在Spring Boot中創(chuàng)建和配置線程池,包括設置線程池的大小、隊列容量、線程名稱等參數(shù),感興趣的可以了解一下

一.線程池簡介

1.1.什么是線程池

線程池是一種利用池化技術思想來實現(xiàn)的線程管理技術,主要是為了復用線程、便利地管理線程和任務、并將線程的創(chuàng)建和任務的執(zhí)行解耦開來。我們可以創(chuàng)建線程池來復用已經(jīng)創(chuàng)建的線程來降低頻繁創(chuàng)建和銷毀線程所帶來的資源消耗。在JAVA中主要是使用ThreadPoolExecutor類來創(chuàng)建線程池,并且JDK中也提供了Executors工廠類來創(chuàng)建線程池(不推薦使用)。

1.2.線程池的優(yōu)點

降低資源消耗,復用已創(chuàng)建的線程來降低創(chuàng)建和銷毀線程的消耗。提高響應速度,任務到達時,可以不需要等待線程的創(chuàng)建立即執(zhí)行。提高線程的可管理性,使用線程池能夠統(tǒng)一的分配、調(diào)優(yōu)和監(jiān)控。

1.3.線程池五種狀態(tài)

線程池ThreadPoolExecutor分別有五種狀態(tài)分別為:RUNNING、SHUTDOWN、STOP、TIDYING、TERMINATED使用一個AtomicInteger類型的ctl字段來描述線程池地運行狀態(tài)和線程數(shù)量,通過ctl的高三位來表示線程池的5種狀態(tài),低29位表示線程池中現(xiàn)有的線程數(shù)量。

 private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
    /**
     * 線程池線程數(shù)地bit數(shù)
     */
    private static final int COUNT_BITS = Integer.SIZE - 3;
    /**
     * 線程池中最大線程容量
     */
    private static final int CAPACITY = (1 << COUNT_BITS) - 1;
    /**
     * 表示可接受新任務,且可執(zhí)行隊列中的任務;
     */
    private static final int RUNNING = -1 << COUNT_BITS;
    /**
     * 表示不接受新任務,但可執(zhí)行隊列中的任務;
     */
    private static final int SHUTDOWN = 0 << COUNT_BITS;
    /**
     * 表示不接受新任務,且不再執(zhí)行隊列中的任務,且中斷正在執(zhí)行的任務;
     */
    private static final int STOP = 1 << COUNT_BITS;
    /**
     * 所有任務已經(jīng)中止,且工作線程數(shù)量為0,最后變遷到這個狀態(tài)的線程將
     * 要執(zhí)行terminated()鉤子方法,只會有一個線程執(zhí)行這個方法;
     */
    private static final int TIDYING = 2 << COUNT_BITS;
    /**
     * TERMINATED,中止狀態(tài),已經(jīng)執(zhí)行完terminated()鉤子方法;
     */
    private static final int TERMINATED = 3 << COUNT_BITS;

線程池狀態(tài)之間的流轉(zhuǎn)圖如下所示

1.4.線程池處理流程

線程池處理流程代碼如下所示

    /**
     * 在將來某個時候執(zhí)行給定的任務。該任務可以在新線程中執(zhí)行,也可以在現(xiàn)有的池線程中執(zhí)行。如果由于此執(zhí)行
     * 器已關閉或已達到其容量,任務無法提交執(zhí)行,則由當前RejectedExecutionHandler處理該任務。
     * Params:
     * 命令–要執(zhí)行的任務
     * Throws:
     * RejectedExecutionException–如果任務無法接受執(zhí)行,則由RejectedExecutionHandler自行決定
     * NullPointerException–如果命令為null
     */
    public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        /*
         分三步走:
         1.如果運行的線程少于corePoolSize,請嘗試以給定的命令作為第一個任務來啟動一個新線程。
         對addWorker的調(diào)用原子地檢查runState和workerCount,因此,通過返回false,可以防止
         在不應該添加線程的情況下添加線程的錯誤警報。
         2.如果一個任務可以成功排隊,那么我們?nèi)匀恍枰屑殭z查我們是否應該添加一個線程(因為自上
         次檢查以來已有的線程已經(jīng)失效),或者池是否在進入該方法后關閉。因此,如果有必要,我們重
         新檢查狀態(tài),如果停止,則回滾排隊,如果workerCount為0,則啟動一個新線程。
         3.如果我們不能對任務進行排隊,那么我們嘗試添加一個新線程。如果它失敗了,我們知道線程池
         被關閉或飽和了,所以拒絕了這項任務。
         */
        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (!isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        } else if (!addWorker(command, false))
            reject(command);
    }

線程池處理流程圖如下所示

二.開始配置

ThreadPoolTaskExecutor是spring core包中的,而ThreadPoolExecutor是JDK中的JUC。ThreadPoolTaskExecutor是對ThreadPoolExecutor進行了封裝處理。

2.1.依賴導入

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<optional>true</optional>
</dependency>

2.2.配置application.properties文件

universe.thread.pool.executor.threadNamePrefix=threadPoolTaskExecutor-
universe.thread.pool.executor.queueCapacity=100
universe.thread.pool.executor.rejectedExecutionHandler=java.util.concurrent.ThreadPoolExecutor$AbortPolicy
universe.thread.pool.executor.keepAliveSeconds=60

2.3.創(chuàng)建PoolExecutorConfig.java

package com.temperature.humidity.system.config.thread;
import lombok.Data;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
@Data
@Log4j2
public class PoolExecutorConfig {
    /**
     * 獲取CPU核數(shù)
     */
    private static final int CPU_NUM;
    /**
     * 配置線程池的前綴
     */
    @Value("${universe.thread.pool.executor.threadNamePrefix}")
    private String threadNamePrefix;
    /**
     * 線程池的核心線程數(shù)。在沒有設置 allowCoreThreadTimeOut 為 true 的情況下,
     * 核心線程會在線程池中一直存活,即使處于閑置狀態(tài)。
     */
    private Integer corePoolSize;
    /**
     * 線程池中的任務隊列,通過線程池的 execute() 方法提交的 Runnable
     * 對象會存儲在該隊列中。
     */
    @Value("${universe.thread.pool.executor.queueCapacity}")
    private Integer queueCapacity;
    /**
     * 線程池所能容納的最大線程數(shù)。當活動線程(核心線程+非核心線程)達到這個數(shù)值后,
     * 后續(xù)任務將會根據(jù) RejectedExecutionHandler 來進行拒絕策略處理。
     */
    private Integer maxPoolSize;
    /**
     * 當任務無法被執(zhí)行時(超過線程最大容量 maximum 并且 workQueue 已經(jīng)被排滿了)的處理策略,
     * - AbortPolicy:丟棄任務并拋出RejectedExecutionException異常
     * - DiscardPolicy:丟棄任務,但是不拋出異常。
     * - DiscardOldestPolicy:丟棄隊列最前面的任務,然后重新提交被拒絕的任務
     * - CallerRunsPolicy:由調(diào)用線程(提交任務的線程)處理該任務
     */
    @Value("${universe.thread.pool.executor.rejectedExecutionHandler}")
    private String rejectedExecutionHandler;
    /**
     * 非核心線程 閑置時的超時時長。超過該時長,非核心線程就會被回收。若線程池通設置
     * 核心線程也允許 timeOut,即 allowCoreThreadTimeOut 為 true,則該時長
     * 同樣會作用于核心線程,在超過aliveTime 時,核心線程也會被回收,AsyncTask
     * 配置的線程池就是這樣設置的。
     */
    @Value("${universe.thread.pool.executor.keepAliveSeconds}")
    private Integer keepAliveSeconds;
    public PoolExecutorConfig() {
        log.info("該臺服務器的CPU核心數(shù)為{}", CPU_NUM);
        this.corePoolSize = CPU_NUM + 1;
        this.maxPoolSize = 2 * CPU_NUM;
    }
    static {
        CPU_NUM = Runtime.getRuntime().availableProcessors();
    }
}

2.4.創(chuàng)建OurPoolExecutor.java

package com.temperature.humidity.system.config.thread;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionHandler;
/**
 * @description 線程池配置類
 */
@Configuration
@Log4j2
public class OurPoolExecutor {
    @Autowired
    private PoolExecutorConfig threadPoolExecutorConfig;
    @Bean
    public Executor threadPoolTaskExecutor() {
        String threadNamePrefix = threadPoolExecutorConfig.getThreadNamePrefix();
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        try {
            log.info("開始初始化線程池 -->threadPoolTaskExecutor");
            taskExecutor.setThreadNamePrefix(threadNamePrefix);
            taskExecutor.setCorePoolSize(threadPoolExecutorConfig.getCorePoolSize());
            taskExecutor.setMaxPoolSize(threadPoolExecutorConfig.getMaxPoolSize());
            taskExecutor.setQueueCapacity(threadPoolExecutorConfig.getQueueCapacity());
            //通過反射獲取RejectedExecutionHandlerClass 的類模板
            Class<?> rejectedExecutionHandlerClass = Class.forName(threadPoolExecutorConfig.getRejectedExecutionHandler());
            //獲取RejectedExecutionHandlerClass類的實例
            RejectedExecutionHandler rejectedExecutionHandler = (RejectedExecutionHandler) rejectedExecutionHandlerClass.newInstance();
            taskExecutor.setRejectedExecutionHandler(rejectedExecutionHandler);
            taskExecutor.setKeepAliveSeconds(threadPoolExecutorConfig.getKeepAliveSeconds());
            //進行加載
            taskExecutor.initialize();
            log.info("初始化線程池完成:{}核心線程為{}-->", threadNamePrefix, taskExecutor.getCorePoolSize());
            return taskExecutor;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("初始化線程池失敗:{}失敗原因為:{}", threadNamePrefix, e.getMessage());
            return null;
        }
    }
}

三.測試

我們配置線程池后啟動我們的SpringBoot項目,可以看到我們的控制臺打印出來了如下圖中圈中的日志,測試成功。

到此這篇關于SpringBoot配置線程池的實現(xiàn)示例的文章就介紹到這了,更多相關SpringBoot 線程池內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家! 

相關文章

  • 如何用Java實現(xiàn)排列組合算法

    如何用Java實現(xiàn)排列組合算法

    本文主要介紹了如何用Java實現(xiàn)排列組合算法,對算法感興趣的同學,可以參考一下,理解其原理,并且試驗一下。
    2021-05-05
  • Java?Bean所有拷貝方式使用方法及性能比較詳解

    Java?Bean所有拷貝方式使用方法及性能比較詳解

    在Java開發(fā)中,常常需要將一個對象的屬性值拷貝到另一個對象中,下面這篇文章主要介紹了Java?Bean所有拷貝方式使用方法及性能比較的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2025-10-10
  • java導出生成word的簡單方法

    java導出生成word的簡單方法

    這篇文章主要為大家詳細介紹了java導出生成word的簡單方法,感興趣的朋友可以參考一下
    2016-03-03
  • Windows下安裝ElasticSearch的方法(圖文)

    Windows下安裝ElasticSearch的方法(圖文)

    這篇文章主要介紹了Windows下安裝ElasticSearch的方法(圖文),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • 深入理解spring的AOP機制原理

    深入理解spring的AOP機制原理

    本篇文章主要介紹了深入理解spring的AOP機制原理,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • SpringBoot框架中Mybatis-plus的簡單使用操作匯總

    SpringBoot框架中Mybatis-plus的簡單使用操作匯總

    這篇文章主要介紹了SpringBoot框架中Mybatis-plus的簡單使用,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-02-02
  • Mybatis中SQL的執(zhí)行過程詳解

    Mybatis中SQL的執(zhí)行過程詳解

    MyBatis框架通過映射文件或注解將Java代碼中的方法與數(shù)據(jù)庫操作進行映射,執(zhí)行過程包括SQL解析、參數(shù)綁定、SQL預編譯、執(zhí)行、結(jié)果映射、事務處理、緩存處理和日志記錄
    2024-12-12
  • IDEA集成JProfiler的圖文詳解

    IDEA集成JProfiler的圖文詳解

    本文詳細介紹了JProfiler的下載、安裝和使用過程,首先需要在官網(wǎng)下載對應操作系統(tǒng)的安裝包并進行安裝,然后填寫個人信息進行注冊并獲取許可證密鑰,感興趣的朋友一起看看吧
    2024-10-10
  • 一篇文章教你如何用Java自定義一個參數(shù)校驗器

    一篇文章教你如何用Java自定義一個參數(shù)校驗器

    這篇文章主要介紹了使用java自定義一個參數(shù)校驗器,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習
    2021-09-09
  • Prometheus監(jiān)控Springboot程序的實現(xiàn)方法

    Prometheus監(jiān)控Springboot程序的實現(xiàn)方法

    這篇文章主要介紹了Prometheus監(jiān)控Springboot程序的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03

最新評論

理塘县| 都兰县| 习水县| 弋阳县| 南开区| 敖汉旗| 固安县| 承德市| 英超| 拉萨市| 岚皋县| 龙川县| 甘南县| 衡阳市| 渭源县| 望城县| 泸州市| 二连浩特市| 集安市| 雷山县| 郑州市| 瓮安县| 宕昌县| 堆龙德庆县| 金沙县| 密云县| 呼玛县| 全州县| 中方县| 分宜县| 江川县| 辽宁省| 余姚市| 恩平市| 光泽县| 台州市| 登封市| 西青区| 南川市| 右玉县| 乌恰县|