線程池拒絕策略四大“送命題”:答錯(cuò)一個(gè),offer直接涼涼!
線程池的拒絕策略是指,當(dāng)線程池?zé)o法承載更多任務(wù)時(shí)執(zhí)行的行為。也就是當(dāng)線程池的核心線程數(shù)、最大線程、任務(wù)隊(duì)列都滿的情況下,又來了新的任務(wù)時(shí),線程池執(zhí)行的行為被稱之為線程池的拒絕策略。
線程池的執(zhí)行流程如下:
1.內(nèi)置拒絕策略
在 Java 中,線程池內(nèi)置了以下四種拒絕策略(Rejected Execution Policy)。
(1)AbortPolicy(中止策略)
- 行為:默認(rèn)拒絕策略,直接拋出 RejectedExecutionException 異常。
- 特點(diǎn):強(qiáng)制調(diào)用方處理任務(wù)被拒絕的情況。
- 適用場景:對任務(wù)丟失不敏感的場景。如果對丟失敏感需結(jié)合異常捕獲機(jī)制處理(記錄信息并告警)。
示例代碼:
new ThreadPoolExecutor(..., new ThreadPoolExecutor.AbortPolicy());
(2)CallerRunsPolicy(調(diào)用者運(yùn)行策略)
- 行為:將任務(wù)退回給提交任務(wù)的線程(即調(diào)用 execute() 的線程),由該線程直接執(zhí)行任務(wù)。
- 特點(diǎn):變相降低任務(wù)提交速度,避免線程池過載。
- 適用場景:希望任務(wù)最終被處理,且能承受一定延遲(如日志記錄)。
示例效果:
// 假設(shè)線程池已滿,主線程提交任務(wù)時(shí)會(huì)直接執(zhí)行該任務(wù)
executor.execute(task); // 主線程執(zhí)行 task
(3)DiscardPolicy(丟棄策略)
- 行為:靜默丟棄被拒絕的任務(wù),不拋出異常,也不執(zhí)行任務(wù)。
- 特點(diǎn):無感知丟棄,可能導(dǎo)致數(shù)據(jù)丟失。
- 適用場景:允許任務(wù)丟失的非關(guān)鍵場景(如實(shí)時(shí)監(jiān)控?cái)?shù)據(jù)采樣)。
示例代碼:
new ThreadPoolExecutor(..., new ThreadPoolExecutor.DiscardPolicy());
(4)DiscardOldestPolicy(丟棄最舊任務(wù)策略)
- 行為:丟棄工作隊(duì)列中等待時(shí)間最長的任務(wù)(即隊(duì)列頭部的任務(wù)),然后重新嘗試提交當(dāng)前任務(wù)。
- 特點(diǎn):優(yōu)先處理新任務(wù),但可能丟失重要舊任務(wù)。
- 適用場景:適合處理時(shí)效性較強(qiáng)的任務(wù)(如消息推送,新任務(wù)優(yōu)先級更高)。
示例代碼:
new ThreadPoolExecutor(..., new ThreadPoolExecutor.DiscardOldestPolicy());
2.自定義拒絕策略
除了以上四種內(nèi)置拒絕策略之外,程序中還可以通過實(shí)現(xiàn) RejectedExecutionHandler 接口實(shí)現(xiàn)自定義策略:
public class CustomRejectionPolicy implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable task, ThreadPoolExecutor executor) {
// 自定義邏輯(如記錄日志、持久化任務(wù)、重試等)
System.out.println("Task rejected: " + task);
// 保存任務(wù)信息
// 通知相關(guān)負(fù)責(zé)人
}
}
// 使用自定義策略
ThreadPoolExecutor executor = new ThreadPoolExecutor(
corePoolSize, maxPoolSize, keepAliveTime, unit, workQueue, new CustomRejectionPolicy()
);
小結(jié)
策略 | 優(yōu)點(diǎn) | 缺點(diǎn) | 適用場景 |
AbortPolicy | 默認(rèn)拒絕策略,報(bào)錯(cuò)提示 | 需處理異常,增加代碼復(fù)雜度 | 任務(wù)丟失不敏感的場景 |
CallerRunsPolicy | 任務(wù)一定執(zhí)行 | 可能阻塞主線程,影響響應(yīng)速度 | 非實(shí)時(shí)任務(wù),允許延遲處理(如日志) |
DiscardPolicy | 簡單高效,無額外開銷 | 數(shù)據(jù)丟失風(fēng)險(xiǎn)高 | 可容忍數(shù)據(jù)丟失的場景(如監(jiān)控采樣) |
DiscardOldestPolicy | 優(yōu)先處理新任務(wù) | 可能丟失重要舊任務(wù) | 時(shí)效性強(qiáng)的任務(wù)(如實(shí)時(shí)消息推送) |
CustomRejectionPolicy | 靈活 | 實(shí)現(xiàn)復(fù)雜 | 通常用于生產(chǎn)環(huán)境,先保存任務(wù)信息,再報(bào)警提示負(fù)責(zé)人 |