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
