SpringBoot中线程池的自定义与使用方法总结,以及定时任务的设置

自定义线程池

SpringBoot中对线程池的自定义分为两种:

  1. 修改默认的线程池
  2. 创建新的自定义线程池

1. 修改默认的线程池

修改默认的线程池,需要创建配置类:

  1. 加入两个注解:
  1. @EnableAsync 开启异步执行功能
  2. @Configuration Spring配置类
  1. 实现AsyncConfigurer接口,并实现两个方法:
  1. public Executor getAsyncExecutor():注意在返回Executor必须初始化executor.initialize()
  2. public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler()
/** 修改默认线程池 */
@Slf4j
@EnableAsync
@Configuration
public class DefaultThreadPoolConfig implements AsyncConfigurer {
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //核心线程池大小
        executor.setCorePoolSize(10);
        //最大线程数
        executor.setMaxPoolSize(20);
        //队列容量
        executor.setQueueCapacity(20);
        //活跃时间
        executor.setKeepAliveSeconds(60);
        //线程名字前缀
        executor.setThreadNamePrefix("DiyThreadPool_");
        // 拒绝策略
        executor.setRejectedExecutionHandler(
                new ThreadPoolExecutor.CallerRunsPolicy()
        );
        // 停机是否等待任务
        executor.setWaitForTasksToCompleteOnShutdown(true);
        // 停机等待任务的最大时长
        executor.setAwaitTerminationSeconds(60);

        // 线程池初始化
        executor.initialize();
        return executor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new AsyncUncaughtExceptionHandler(){
            @Override
            public void handleUncaughtException(Throwable throwable,
                                                Method method,
                                                Object... objects) {
                throwable.printStackTrace();
                log.error("AsyncError: {}, Method: {}",
                        throwable.getMessage(), method.getName());
            }
        };
    }
}

2. 创建新的自定义线程池

直接在Spring配置类中创建返回Executor的方法,并加上@Bean注解注册为Bean。

/** 自定义线程池 */
@Configuration
public class MyThreadPool {
    @Bean
    public Executor MyThreadPool() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //核心线程池大小
        executor.setCorePoolSize(10);
        //最大线程数
        executor.setMaxPoolSize(20);
        //队列容量
        executor.setQueueCapacity(20);
        //活跃时间
        executor.setKeepAliveSeconds(60);
        //线程名字前缀
        executor.setThreadNamePrefix("MyThreadPool_");
        // 拒绝策略
        executor.setRejectedExecutionHandler(
                new ThreadPoolExecutor.CallerRunsPolicy()
        );
        // 停机是否等待任务
        executor.setWaitForTasksToCompleteOnShutdown(true);
        // 停机等待任务的最大时长
        executor.setAwaitTerminationSeconds(60);

        executor.initialize();
        return executor;
    }
}

线程池的使用

在需要开启异步执行的方法上,加上注解@Async(value)开启异步执行,这里的参数分为几种情况:

  1. 不填 或 "":采用默认的线程池,如果修改过默认线程池,则使用修改过的配置
  2. "taskScheduler":无论是否修改过默认线程池,都使用修改前的默认配置
  3. 自定义线程池类名:使用指定的自定义线程池,注意这里是类名(即注册为Bean的名字)
@Slf4j
public class Task {
    @Async("MyThreadPool")
    public void cleanExpiredTemplate_(){
        log.info(Thread.currentThread().getName() + ": Task is finished");
    }
}

若任务为定时任务:

  1. 在SpringBoot启动类上加注解@EnableScheduling开启定时任务功能并自动扫描。
  2. 在任务方法所在类上加注解@Component,从而被扫描到。
  3. 在任务方法上加注解@Scheduled,定义执行规则。这个注解的参数有很多种。如:
  1. fixedRate:单位为毫秒。间隔时间执行。