springboot 集成异步线程池
目的:通过实现AsyncConfigurer自定义线程池,包含异常处理。 实现AsyncConfigurer接口对异常线程池更加细粒度的控制
/** * @Description: 线程池配置 * @Author: mingtian * @CreateDate: 2020/11/12 15:57 * @Version: 1.0 */ @Configuration @EnableAsync public class ThreadPoolConfig implements AsyncConfigurer { /** * 打印日志 */ private Logger logger = LoggerFactory.getLogger(getClass()); /** * cpu 核心数量 */ public static final int cpuNum = Runtime.getRuntime().availableProcessors(); /** * 线程池配置 * * @return */ @Bean("taskExecutor") @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); // 配置核心线程池数量 taskExecutor.setCorePoolSize(cpuNum); // 配置最大线程池数量 taskExecutor.setMaxPoolSize(cpuNum * 2); /// 线程池所使用的缓冲队列 taskExecutor.setQueueCapacity(2); // 等待时间 (默认为0,此时立即停止),并没等待xx秒后强制停止 taskExecutor.setAwaitTerminationSeconds(60); // 空闲线程存活时间 taskExecutor.setKeepAliveSeconds(60); // 等待任务在关机时完成--表明等待所有线程执行完 taskExecutor.setWaitForTasksToCompleteOnShutdown(true); // 线程池名称前缀 taskExecutor.setThreadNamePrefix("thread-pool-"); // 线程池拒绝策略 taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy()); // 线程池初始化 taskExecutor.initialize(); logger.info("线程池初始化......"); return taskExecutor; } /** * 重写捕获异常类 * * @return */ @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return new MyAsyncExceptionHandler(); } /** * 自定义异常处理类 */ class MyAsyncExceptionHandler implements AsyncUncaughtExceptionHandler { //手动处理捕获的异常 @Override public void handleUncaughtException(Throwable throwable, Method method, Object... obj) { logger.error("ExceptionMessage:{}", throwable.getMessage()); logger.error("MethodName:{}", method.getName()); for (Object param : obj) { logger.error("Parameter:{}", param); } } } }
模拟发送消息业务层
1 /** 2 * @Description: 模拟异步发送消息方法 3 * @Author: mingtian 4 * @CreateDate: 2020/11/12 16:29 5 * @Version: 1.0 6 */ 7 @Component 8 public class SendMessageService { 9 /** 10 * 打印日志 11 */ 12 private Logger logger = LoggerFactory.getLogger(getClass()); 13 14 @Async 15 public void sendMessage() { 16 logger.info("发送消息"); 17 System.out.println("子线程名称:" + Thread.currentThread().getName()); 18 } 19 }
测试类
1 /** 2 * @Description: 测试类 3 * @Author: mingtian 4 * @CreateDate: 2020/11/12 16:30 5 * @Version: 1.0 6 */ 7 @RunWith(SpringRunner.class) 8 @SpringBootTest 9 public class Test { 10 @Autowired 11 private SendMessageService messageService; 12 13 @org.junit.Test 14 public void testAsync() { 15 System.out.println("主线程名称:" + Thread.currentThread().getName()); 16 for (int i = 0; i < 100; i++) { 17 messageService.sendMessage(); 18 } 19 20 } 21 }
控制台打印结果:
主线程名称:main 2020-11-12 16:47:48.985 INFO 16728 --- [ thread-pool-6] c.example.threadpool.SendMessageService : 异步发送发送消息 2020-11-12 16:47:48.985 INFO 16728 --- [ thread-pool-5] c.example.threadpool.SendMessageService : 异步发送发送消息 2020-11-12 16:47:48.985 INFO 16728 --- [ thread-pool-6] c.example.threadpool.SendMessageService : 异步发送发送消息 2020-11-12 16:47:48.985 INFO 16728 --- [ thread-pool-7] c.example.threadpool.SendMessageService : 异步发送发送消息 2020-11-12 16:47:48.985 INFO 16728 --- [ thread-pool-5] c.example.threadpool.SendMessageService : 异步发送发送消息 2020-11-12 16:47:48.985 INFO 16728 --- [ thread-pool-8] c.example.threadpool.SendMessageService : 异步发送发送消息 2020-11-12 16:47:48.985 INFO 16728 --- [ thread-pool-4] c.example.threadpool.SendMessageService : 异步发送发送消息 2020-11-12 16:47:48.985 INFO 16728 --- [ thread-pool-1] c.example.threadpool.SendMessageService : 异步发送发送消息 2020-11-12 16:47:48.985 INFO 16728 --- [ thread-pool-3] c.example.threadpool.SendMessageService : 异步发送发送消息 2020-11-12 16:47:48.985 INFO 16728 --- [ thread-pool-2] c.example.threadpool.SendMessageService : 异步发送发送消息
由以上的结果得出配置的线程池是有效的。
创建线程池方法博客:https://www.cnblogs.com/ming-blogs/p/10555997.html