天天看點

SpringBoot 線程池配置

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  : 異步發送發送消息      

由以上的結果得出配置的線程池是有效的。