这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战
目的
在线程池提交线程实现声明周期的日志打印,包括线程任务被拒绝
思路
正常来说线程池执行线程任务是没有任何日志的,但是我们可以替换这个线程对象,就想spring 替换对象实现切面一样
代码
@Slf4j
public class RunnableExWrapper implements Runnable {
final Runnable runnable;
public RunnableExWrapper(Runnable runnable) {
this.runnable = runnable;
}
public static RunnableExWrapper of(Runnable r) {
return of(r);
}
public void rejectCallback(){
Optional.ofNullable(notify).ifPresent(Notify::reject);
log.info("线程拒绝由当前线程执行");
this.runnable.run();
}
@Override
public void run() {
// 线程开始运行
try {
this.runnable.run();
} catch (Exception e) {
// 线程运行异常
}
// 线程运行结束
}
}
自定义线程拒绝策略
/**
* 自定义线程拒绝策略
*/
@Slf4j
public class AppRejectedExHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
// log.info("当前线程拒绝 ===> {}", r.toString());
if (r instanceof RunnableExWrapper) {
RunnableExWrapper runnableExWrapper = (RunnableExWrapper) r;
runnableExWrapper.rejectCallback();
}
}
}
在spring 中注册一个线程池
public ThreadPoolTaskExecutor commonCreateThreadPool(String namePrefix, int threadNum, Integer maxNum,Integer queueCapacitySize) {
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
/**核心线程数*/
threadPoolTaskExecutor.setCorePoolSize(threadNum);
/**维护线程最大数量*/
threadPoolTaskExecutor.setMaxPoolSize(Optional.ofNullable(maxNum).orElse(maxPoolSize));
/**允许的空闲时间*/
threadPoolTaskExecutor.setKeepAliveSeconds(keepAliveSeconds);
/**任务队列 最大线程队列应该 > max + core*/
threadPoolTaskExecutor.setQueueCapacity(Optional.ofNullable(queueCapacitySize).orElse(queueCapacity));
threadPoolTaskExecutor.setThreadNamePrefix(namePrefix);
// 等待所有任务结束后再关闭线程池
threadPoolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
//当pool已经达到max size的时候,如何处理新任务
//自定义拒绝策略
threadPoolTaskExecutor.setRejectedExecutionHandler(new AppRejectedExHandler());
// 初始化线程池
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
}
@Bean("msgExecutor")
public TaskExecutor msgExecutor() {
return commonCreateThreadPool("msgExecutor", msgPoolCoreSize, msgPoolMaxSize, queueCapacity);
}
此时提交线程
msgExecutor.execute(RunnableExWrapper.of(() -> {
// 线程任务
System.out.print("ssssssssss")
});