[轉(zhuǎn)]ThreadPoolTaskExecutor使用詳解

配置
ThreadPoolTaskExecutor通常通過XML方式配置,或者通過Executors的工廠方法進(jìn)行配置。
XML方式配置

<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    <property name="corePoolSize" value="8"/> <!--核心線程數(shù) -->
    <property name="maxPoolSize" value="16"/> <!--最大線程數(shù) -->
    <property name="keepAliveSeconds" value ="3000"/> <!--線程最大空閑時間 -->
    <property name="queueCapacity" value="200"/> <!-- 隊列大小 -->
    <property name="threadNamePrefix" value="TASK_EXECUTOR"/>
    <property name="rejectedExecutionHandler">
        <bean class="java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy"/>
    </property>
</bean>

rejectedExecutionHandler字段用于配置拒絕策略,常用的拒絕策略如下:

AbortPolicy,用于被拒絕任務(wù)的處理程序,它將拋出RejectedExecutionException。
CallerRunsPolicy,用于被拒絕任務(wù)的處理程序,它直接在execute方法的調(diào)用線程中運行被拒絕的任務(wù)。
DiscardOldestPolicy,用于被拒絕任務(wù)的處理程序,它放棄最舊的未處理請求,然后重試execute。
DiscardPolicy,用于被拒絕任務(wù)的處理程序,默認(rèn)情況下它將丟棄被拒絕的任務(wù)。
其他說明:

為了實現(xiàn)某些特殊的業(yè)務(wù)需求,用戶可以選擇使用自定義策略,只需實現(xiàn)RejectedExecutionHandler接口即可。
建議配置threadNamePrefix屬性,出問題時可以更方便的進(jìn)行排查。
提交任務(wù)
無返回值的任務(wù)使用execute(Runnable)
有返回值的任務(wù)使用submit(Runnable)
處理流程
當(dāng)一個任務(wù)被提交到線程池時,首先查看線程池的核心線程是否都在執(zhí)行任務(wù),否就選擇一條線程執(zhí)行任務(wù),是就執(zhí)行第二步。
查看核心線程池是否已滿,不滿就創(chuàng)建一條線程執(zhí)行任務(wù),否則執(zhí)行第三步。
查看任務(wù)隊列是否已滿,不滿就將任務(wù)存儲在任務(wù)隊列中,否則執(zhí)行第四步。
查看線程池是否已滿,不滿就創(chuàng)建一條線程執(zhí)行任務(wù),否則就按照策略處理無法執(zhí)行的任務(wù)。
在ThreadPoolExecutor中表現(xiàn)為:

如果當(dāng)前運行的線程數(shù)小于corePoolSize,那么就創(chuàng)建線程來執(zhí)行任務(wù)(執(zhí)行時需要獲取全局鎖)。
如果運行的線程大于或等于corePoolSize,那么就把task加入BlockQueue。
如果創(chuàng)建的線程數(shù)量大于BlockQueue的最大容量,那么創(chuàng)建新線程來執(zhí)行該任務(wù)。
如果創(chuàng)建線程導(dǎo)致當(dāng)前運行的線程數(shù)超過maximumPoolSize,就根據(jù)飽和策略來拒絕該任務(wù)。
關(guān)閉線程池
調(diào)用shutdown或者shutdownNow,兩者都不會接受新的任務(wù),而且通過調(diào)用要停止線程的interrupt方法來中斷線程,有可能線程永遠(yuǎn)不會被中斷,不同之處在于shutdownNow會首先將線程池的狀態(tài)設(shè)置為STOP,然后嘗試停止所有線程(有可能導(dǎo)致部分任務(wù)沒有執(zhí)行完)然后返回未執(zhí)行任務(wù)的列表。而shutdown則只是將線程池的狀態(tài)設(shè)置為shutdown,然后中斷所有沒有執(zhí)行任務(wù)的線程,并將剩余的任務(wù)執(zhí)行完。

配置線程個數(shù)
如果是CPU密集型任務(wù),那么線程池的線程個數(shù)應(yīng)該盡量少一些,一般為CPU的個數(shù)+1條線程。
如果是IO密集型任務(wù),那么線程池的線程可以放的很大,如2*CPU的個數(shù)。
對于混合型任務(wù),如果可以拆分的話,通過拆分成CPU密集型和IO密集型兩種來提高執(zhí)行效率;如果不能拆分的的話就可以根據(jù)實際情況來調(diào)整線程池中線程的個數(shù)。
監(jiān)控線程池狀態(tài)
常用狀態(tài):

taskCount:線程需要執(zhí)行的任務(wù)個數(shù)。
completedTaskCount:線程池在運行過程中已完成的任務(wù)數(shù)。
largestPoolSize:線程池曾經(jīng)創(chuàng)建過的最大線程數(shù)量。
getPoolSize獲取當(dāng)前線程池的線程數(shù)量。
getActiveCount:獲取活動的線程的數(shù)量
通過繼承線程池,重寫beforeExecute,afterExecute和terminated方法來在線程執(zhí)行任務(wù)前,線程執(zhí)行任務(wù)結(jié)束,和線程終結(jié)前獲取線程的運行情況,根據(jù)具體情況調(diào)整線程池的線程數(shù)量。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容