本文为博主原创,转载请注明出处:
ThreadPoolTaskExecutor 是Spring 中封装的一个类,spring boot中常用 ThreadPoolTaskExecutor 创建线程池,并把它注入到 IOC 容器中,从而可以全局进行使用。
如下为使用 ThreadPoolTaskExecutor 创建的自定义配置的 线程池类:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.Executor; @Configuration @EnableAsync public class ThreadPoolExecutorConfig { @Bean(name="threadPoolExecutor") public Executor threadPoolExecutor(){ ThreadPoolTaskExecutor threadPoolExecutor = new ThreadPoolTaskExecutor(); int processNum = Runtime.getRuntime().availableProcessors(); // 返回可用处理器的Java虚拟机的数量 int corePoolSize = (int) (processNum / (1 - 0.2)); int maxPoolSize = (int) (processNum / (1 - 0.5)); threadPoolExecutor.setCorePoolSize(corePoolSize); // 核心池大小 threadPoolExecutor.setMaxPoolSize(maxPoolSize); // 最大线程数 threadPoolExecutor.setQueueCapacity(maxPoolSize * 1000); // 队列程度 threadPoolExecutor.setThreadPriority(Thread.MAX_PRIORITY); threadPoolExecutor.setDaemon(false); threadPoolExecutor.setKeepAliveSeconds(300);// 线程空闲时间 threadPoolExecutor.setThreadNamePrefix("test-Executor-"); // 线程名字前缀 return threadPoolExecutor; } }
@EnableAsync是与@Async配合使用,用于执行异步任务
使用示例:
@Service public class SpringExecutorTest { @Autowired private Executor threadPoolExecutor; public void test(){ AtomicInteger num = new AtomicInteger(0); for (int i = 0; i < 5; i++) { threadPoolExecutor.execute(()->{ num.incrementAndGet(); }); } System.out.println(num.get()); } }
@Async("threadPoolExecutor") public void asyncTest(){ log.error("threadPoolExecutor asyncTest start"); }
需要注意的是,在使用 @Async 注解时,想使用自定义的 Executor 线程池配置,则需要在 @Async 注解上声明线程池的名称,否则会使用默认的线程池配置。
若想在使用@Async 注解时,不显示声明线程池,且使用定义线程池的配置,可采用以下方式进行配置:
import lombok.extern.slf4j.Slf4j; import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.AsyncConfigurer; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.lang.reflect.Method; import java.util.concurrent.Executor; @Slf4j @Configuration public class NativeAsyncTaskExecutePool implements AsyncConfigurer { @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor threadPoolExecutor = new ThreadPoolTaskExecutor(); int processNum = Runtime.getRuntime().availableProcessors(); // 返回可用处理器的Java虚拟机的数量 int corePoolSize = (int) (processNum / (1 - 0.2)); int maxPoolSize = (int) (processNum / (1 - 0.5)); threadPoolExecutor.setCorePoolSize(corePoolSize); // 核心池大小 threadPoolExecutor.setMaxPoolSize(maxPoolSize); // 最大线程数 threadPoolExecutor.setQueueCapacity(maxPoolSize * 1000); // 队列程度 threadPoolExecutor.setThreadPriority(Thread.MAX_PRIORITY); threadPoolExecutor.setDaemon(false); threadPoolExecutor.setKeepAliveSeconds(300);// 线程空闲时间 threadPoolExecutor.setThreadNamePrefix("test-Executor-"); // 线程名字前缀 return threadPoolExecutor; } /** * 异步任务中异常处理 * @return */ @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return new AsyncUncaughtExceptionHandler() { @Override public void handleUncaughtException(Throwable arg0, Method arg1, Object... arg2) { log.error("=========================="+arg0.getMessage()+"=======================", arg0); log.error("exception method:"+arg1.getName()); } }; } }
当使用以上的方式时,可在使用 @Async 注解时,不用显示生命线程池的方式就可以使用自定义的线程池。
name="threadPoolExecutor"