SpringBoot中的异步线程池

在实际场景中,如后台系统中的生成报表这样的任务需要做较长时间的运算,这样的任务通常开一个新的线程完成,而不是管理人员在点击生成报表后在自己所在的线程内进行长时间的等待,新的线程内经过一段时间运算后生成报表后再将报表提交。这样的业务就需要使用到异步线程池和异步编程。

先使用java配置定义异步线程池和启用异步:

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
          
   
	@Bean
    @Override
    public Executor getAsyncExecutor() {
          
   
        ThreadPoolTaskExecutor executor=new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);//核心线程数
        executor.setMaxPoolSize(10);//最大线程数
        executor.setQueueCapacity(10);//线程队列最大容量
        executor.setRejectedExecutionHandler(
        new ThreadPoolExecutor.CallerRunsPolicy());//拒绝加入策略
        return executor;
    }
}

如果线程池内线程数小于CorePoolSize则创建新线程,如果线程数等于CorePoolSize,会向线程队列中加入任务,如果线程队列中已加满任务,将会扩大线程池,直至线程数达到最大线程数,之后再加入线程会触发拒绝策略。 一般用到以下四个线程池拒绝策略

    ThreadPoolExecutor.AbortPolicy:抛出 RejectedExecutionException来拒绝新任务的处理。默认是这种策略 ThreadPoolExecutor.CallerRunsPolicy:用调用者所在的线程来执行任务。但是这种策略会降低对于新任务提交速度,影响程序的整体性能。如果您的应用程序可以承受此延迟并且你不能任务丢弃任何一个任务请求的话,你可以选择这个策略。 ThreadPoolExecutor.DiscardPolicy: 不处理新任务,直接丢弃掉。 ThreadPoolExecutor.DiscardOldestPolicy: 此策略将丢弃最早的未处理的任务请求。

用@Async注解方法,声明使用异步调用

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

@Service
public class AsyncService {
          
   
    @Async
    void asyncMethod(String name){
          
   
        System.out.println(name);
        System.out.println("线程名称:"+Thread.currentThread().getName());
    }
}
经验分享 程序员 微信小程序 职场和发展