ThreadPoolTaskExecutor和ThreadPoolExecutor


1、ThreadPoolExecutor

 

 線程池接口:ExecutorService為線程池接口,提供了線程池生命周期方法,繼承自Executor接口,ThreadPoolExecutor為線程池實現類,提供了線程池的維護操作等相關方法,繼承自AbstractExecutorService,AbstractExecutorService實現了ExecutorService接口。

工具類 : Executors

Executors為線程遲工具類,相當於一個工廠類,用來創建合適的線程池,返回ExecutorService類型的線程池。有如下方法。
ExecutorService newFixedThreadPool() : 創建固定大小的線程池
ExecutorService newCachedThreadPool() : 緩存線程池,線程池的數量不固定,可以根據需求自動的更改數量。
ExecutorService newSingleThreadExecutor() : 創建單個線程池。 線程池中只有一個線程

ScheduledExecutorService newScheduledThreadPool() : 創建固定大小的線程,可以延遲或定時的執行任務

其中AbstractExecutorService是他的抽象父類,繼承自ExecutorService,ExecutorService 接口擴展Executor接口,增加了生命周期方法。

2.ThreadPoolTaskExecutor

這個類則是spring包下的,是sring為我們提供的線程池類,這里重點講解這個類的用法,可以使用基於xml配置的方式創建

    <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <!-- 核心線程數  -->
        <property name="corePoolSize" value="10"/>
        <!-- 最大線程數 -->
        <property name="maxPoolSize" value="200"/>
        <!-- 隊列最大長度 >=mainExecutor.maxSize -->
        <property name="queueCapacity" value="10"/>
        <!-- 線程池維護線程所允許的空閑時間 -->
        <property name="keepAliveSeconds" value="20"/>
        <!-- 線程池對拒絕任務(無線程可用)的處理策略 -->
        <property name="rejectedExecutionHandler">
            <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy"/>
        </property>
    </bean>

然后通過自動注入的方式注入線程池,

@Resource(name="taskExecutor")
ThreadPoolTaskExecutor taskExecutor;
// 或者可以直接@Autowried
@AutoWired
ThreadPoolTaskExecutor taskExecutor

或者是通過配置類的方式配置線程池,然后注入。

@Configuration
public class ExecturConfig {
    @Bean("taskExector")
    public Executor taskExector() {
 
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        int i = Runtime.getRuntime().availableProcessors();//獲取到服務器的cpu內核
        executor.setCorePoolSize(5);//核心池大小
        executor.setMaxPoolSize(100);//最大線程數
        executor.setQueueCapacity(1000);//隊列程度
        executor.setKeepAliveSeconds(1000);//線程空閑時間
        executor.setThreadNamePrefix("tsak-asyn");//線程前綴名稱
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());//配置拒絕策略
        return executor;
    }

提交任務

  • 無返回值的任務使用execute(Runnable)
  • 有返回值的任務使用submit(Runnable)

 

上面注解中已經注釋了參數的詳解,這里重點講解一下spring線程池的拒絕策略和處理流程。

    拒絕策略

rejectedExectutionHandler參數字段用於配置絕策略,常用拒絕策略如下

AbortPolicy:用於被拒絕任務的處理程序,它將拋出RejectedExecutionException

CallerRunsPolicy:用於被拒絕任務的處理程序,它直接在execute方法的調用線程中運行被拒絕的任務。

DiscardOldestPolicy:用於被拒絕任務的處理程序,它放棄最舊的未處理請求,然后重試execute。

DiscardPolicy:用於被拒絕任務的處理程序,默認情況下它將丟棄被拒絕的任務。

其他說明:

  1. 為了實現某些特殊的業務需求,用戶可以選擇使用自定義策略,只需實現RejectedExecutionHandler接口即可。
  2. 建議配置threadNamePrefix屬性,出問題時可以更方便的進行排查。



    處理流程

1.當一個任務被提交到線程池時,首先查看線程池的核心線程是否都在執行任務,否就選擇一條線程執行任務,就是執行第二步。

2.查看核心線程池是否已滿,不滿就創建一條線程執行任務,否則執行第三步。

3.查看任務隊列是否已滿,不滿就將任務存儲在任務隊列中,否則執行第四步。

4.查看線程池是否已滿,不滿就創建一條線程執行任務,否則就按照策略處理無法執行的任務。

流程圖如下

 

監控線程池狀態

常用狀態:

    taskCount:線程需要執行的任務個數。
    completedTaskCount:線程池在運行過程中已完成的任務數。
    largestPoolSize:線程池曾經創建過的最大線程數量。
    getPoolSize獲取當前線程池的線程數量。
    getActiveCount:獲取活動的線程的數量


參考:ThreadPoolTaskExecutor使用詳解

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM