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:用於被拒絕任務的處理程序,默認情況下它將丟棄被拒絕的任務。
其他說明:
- 為了實現某些特殊的業務需求,用戶可以選擇使用自定義策略,只需實現
RejectedExecutionHandler
接口即可。 - 建議配置
threadNamePrefix
屬性,出問題時可以更方便的進行排查。
處理流程
1.當一個任務被提交到線程池時,首先查看線程池的核心線程是否都在執行任務,否就選擇一條線程執行任務,就是執行第二步。
2.查看核心線程池是否已滿,不滿就創建一條線程執行任務,否則執行第三步。
3.查看任務隊列是否已滿,不滿就將任務存儲在任務隊列中,否則執行第四步。
4.查看線程池是否已滿,不滿就創建一條線程執行任務,否則就按照策略處理無法執行的任務。
流程圖如下
監控線程池狀態
常用狀態:
taskCount:線程需要執行的任務個數。
completedTaskCount:線程池在運行過程中已完成的任務數。
largestPoolSize:線程池曾經創建過的最大線程數量。
getPoolSize獲取當前線程池的線程數量。
getActiveCount:獲取活動的線程的數量