自定义线程池拒绝策略步骤
- 实现
RejectedExecutionHandler
接口,该接口只有一个方法rejectedExecution(Runnable r, ThreadPoolExecutor executor)
。
- 在实现类中编写自定义的拒绝逻辑。例如,可以记录被拒绝任务的相关信息,尝试重新提交任务,或者根据业务需求采取其他处理方式。
示例代码
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
public class CustomRejectedExecutionHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
System.out.println("任务 " + r.toString() + " 被拒绝,线程池状态:" + executor.toString());
// 这里可以添加自定义处理逻辑,如记录日志、尝试重新提交任务等
}
}
使用自定义拒绝策略
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2,
4,
10,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(2),
new CustomRejectedExecutionHandler());
for (int i = 0; i < 10; i++) {
executor.submit(() -> {
try {
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName() + " 执行任务");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
executor.shutdown();
}
}
适用业务场景
- 日志记录场景:在日志收集系统中,当线程池饱和无法处理新的日志记录任务时,默认策略可能直接丢弃任务。而自定义拒绝策略可以将被拒绝的日志任务记录到文件或者其他持久化存储中,保证日志不丢失,便于后续分析。
- 重试场景:在一些订单处理系统中,如果由于系统瞬时负载过高,订单处理任务被线程池拒绝,自定义拒绝策略可以尝试将任务重新提交到线程池,或者发送到一个延迟队列稍后处理,以确保订单最终能够被处理,而不是像默认策略那样直接丢弃任务导致订单处理失败。