SpringBoot 使用线程池

前言

一、SpringBoot 中线程池的使用

在实际项目中我们经常会遇到这样的场景需求,例如需要一个接口需要执行一个需要花费时间很长执行的任务,但是我们不想由于这个任务导致接口主线程阻塞,这时候我们需要其它线程去执行这个任务,这就需要使用到线程池。

1.1、配置线程池

@Configuration
// 开启多线程
@EnableAsync
public class ThreadPoolConfig {

    @Value("${myThreadPool.maxPoolSize}")
    private Integer maxPoolSize;
    @Value("${myThreadPool.queueCapacity}")
    private Integer queueCapacity;
    @Value("${myThreadPool.keepAliveSeconds}")
    private Integer keepAliveSeconds;
    @Value("${myThreadPool.threadNamePrefix}")
    private String threadNamePrefix;
    @Value("${myThreadPool.waitForTasksToCompleteOnShutdown}")
    private Boolean waitForTasksToCompleteOnShutdown;


    @Bean("taskExecutor")
    public Executor asyncServiceExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 设置核心线程数等于系统核数
        int availableProcessors = Runtime.getRuntime().availableProcessors();
        // 设置核心线程数
        executor.setCorePoolSize(availableProcessors);
        // executor.setCorePoolSize(corePoolSize);
        // 设置最大线程数
        executor.setMaxPoolSize(maxPoolSize);
        // 设置队列大小
        executor.setQueueCapacity(queueCapacity);
        // 设置线程活跃时间(秒)
        executor.setKeepAliveSeconds(keepAliveSeconds);
        // 线程满了之后由调用者所在的线程来执行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 设置默认线程名称
        executor.setThreadNamePrefix(threadNamePrefix);
        // 等待所有任务执行完成后再关闭线程池
        executor.setWaitForTasksToCompleteOnShutdown(waitForTasksToCompleteOnShutdown);
        // 执行初始化
        executor.initialize();
        return executor;
    }

}

线程池的参数配置在application-dev.yml中,具体如下

myThreadPool:
  maxPoolSize: 20
  queueCapacity: 2048
  keepAliveSeconds: 60
  threadNamePrefix: HuDu
  waitForTasksToCompleteOnShutdown: true

1.2、创建异步调用接口以及实现类

这里主要是使用到@Async这个注解来声明使用XXX线程池异步执行该方法,代码如下

public interface ThreadService {
    void syncFile();
}
@Component
@Slf4j
public class ThreadServiceImpl implements ThreadService {

    // 此操作不会影响原有的主线程
    @Async
    @Override
    public void syncFile() {
        log.info("syncFile {}",Thread.currentThread().getName());
    }
}

1.3、线程池测试

@Test
public void threadPoolTest() {
    for (int i = 0; i < 20; i++) {
        threadPoolService.syncFile();
    }
    log.info("主线程 {} 结束执行",Thread.currentThread().getName());
}

执行结果如下

SpringBoot 使用线程池

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!