Spring的執行緒池和JDK的執行緒池的區別?
阿新 • • 發佈:2019-01-27
API 文件中很清楚,SpringFrameWork 的 ThreadPoolTaskExecutor 是輔助 JDK 的 ThreadPoolExecutor 的工具類,它將屬性通過 JavaBeans 的命名規則提供出來,方便進行配置。
1.ThreadPoolExecutor
Spring中的ThreadPoolTaskExecutor是藉助於JDK併發包中的java.util.concurrent.ThreadPoolExecutor來實現的.下面先學習下ThreadPoolExecutor中的相關資訊.ThreadPoolExecutor建構函式如下:
-
public
- int maximumPoolSize,
- long keepAliveTime,
- TimeUnit unit,
- BlockingQueue<Runnable> workQueue,
-
ThreadFactory threadFactory,
- RejectedExecutionHandler handler) {
下面分別說下各項代表的具體意義:
int corePoolSize:執行緒池維護執行緒的最小數量.
int maximumPoolSize:執行緒池維護執行緒的最大數量.
long keepAliveTime:空閒執行緒的存活時間.
TimeUnit unit: 時間單位,現有納秒,微秒,毫秒,秒列舉值.
BlockingQueue<Runnable> workQueue:持有等待執行的任務佇列.
RejectedExecutionHandler handler:
用來拒絕一個任務的執行,有兩種情況會發生這種情況。
一是在execute方法中若addIfUnderMaximumPoolSize(command)為false,即執行緒池已經飽和;
二是在execute方法中, 發現runState!=RUNNING || poolSize == 0,即已經shutdown,就呼叫ensureQueuedTaskHandled(Runnable command),在該方法中有可能呼叫reject。
Reject策略預定義有四種:
(1)ThreadPoolExecutor.AbortPolicy策略,是預設的策略,處理程式遭到拒絕將丟擲執行時 RejectedExecutionException。
(2)ThreadPoolExecutor.CallerRunsPolicy策略 ,呼叫者的執行緒會執行該任務,如果執行器已關閉,則丟棄.
(3)ThreadPoolExecutor.DiscardPolicy策略,不能執行的任務將被丟棄.
(4)ThreadPoolExecutor.DiscardOldestPolicy策略,如果執行程式尚未關閉,則位於工作佇列頭部的任務將被刪除,然後重試執行程式(如果再次失敗,則重複此過程).
2. Spring中ThreadPoolTaskExecutor的使用
最常用方式就是做為BEAN注入到容器中,如下程式碼:
Java程式碼
- <bean id="threadPoolTaskExecutor"
- class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
- <property name="corePoolSize" value="10" />
- <property name="maxPoolSize" value="15" />
- <property name="queueCapacity" value="1000" />
- </bean>
ThreadPoolExecutor執行器的處理流程:
(1)當執行緒池大小小於corePoolSize就新建執行緒,並處理請求.
(2)當執行緒池大小等於corePoolSize,把請求放入workQueue中,池子裡的空閒執行緒就去從workQueue中取任務並處理.
(3)當workQueue放不下新入的任務時,新建執行緒加入執行緒池,並處理請求,如果池子大小撐到了maximumPoolSize就用RejectedExecutionHandler來做拒絕處理.
(4)另外,當執行緒池的執行緒數大於corePoolSize的時候,多餘的執行緒會等待keepAliveTime長的時間,如果無請求可處理就自行銷燬.
瞭解清楚了ThreadPoolExecutor的執行流程,開頭提到的org.springframework.core.task.TaskRejectedException異常也就好理解和解決了.ThreadPoolTaskExecutor類中使用的
就是ThreadPoolExecutor.AbortPolicy()策略,直接丟擲異常.