一、概念
线程池就是将多个线程对象放入一个池子里面,例如一个池塘,线程池就是这个池塘,池塘里面的鱼就是线程池中的多个线程对象。1. 每一个线程,在一段时间内只能执行一个任务。2. 线程池中的各个线程是可以重复使用的。
二、创建线程池的基本步骤
-
添加依赖(如果你使用的是Spring Boot,通常已经包含了必要的依赖):
确保你的
pom.xml
(Maven)或build.gradle
(Gradle)文件中包含了Spring Boot的依赖。 -
配置线程池:
在你的Spring Boot配置类(通常带有
@Configuration
注解)中,你可以创建一个TaskExecutor
的Bean。例如,使用ThreadPoolTaskExecutor
:@Configuration @EnableAsync public class AsyncConfig { @Bean(name = "taskExecutor") public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.setMaxPoolSize(10); executor.setQueueCapacity(25); executor.setThreadNamePrefix("Async-"); executor.initialize(); return executor; } }
注意
@EnableAsync
注解,它启用了异步方法的支持。你可以将此注解放在你的配置类上,或者使用@Async
注解在你的服务或组件中直接指定某个方法为异步执行。线程池的参数说明:
corePoolSize:核心线程数
maximumPoolSize:最大线程数
keepAliveTime:最大空闲时间
unit:最大空闲时间单位
workQueue:任务队列
handler:拒绝策略,有以下四种
(1)ThreadPoolExecutor.AbortPolicy 丢弃任务,并抛出 RejectedExecutionException 异常。
(2)ThreadPoolExecutor.CallerRunsPolicy:该任务被线程池拒绝,由调用 execute方法的线程执行该任务。
(3)ThreadPoolExecutor.DiscardOldestPolicy : 抛弃队列最前面的任务,然后重新尝试执行任务。
(4)ThreadPoolExecutor.DiscardPolicy,丢弃任务,不过也不抛出异常。
也可以自己实现RejectedExecutionHandler接口来自定义拒绝策略
-
使用线程池:
在你的服务或组件中,你可以使用
@Async
注解来指定某个方法应该异步执行,并使用上面配置的线程池。Spring会自动使用你配置的TaskExecutor
来执行这些方法。@Service public class AsyncService { @Autowired private TaskExecutor taskExecutor; // 也可以使用@Qualifier指定具体的Bean名,如@Qualifier("taskExecutor") // 或者你可以直接通过@Async注解并使用默认配置的线程池 @Async public void asyncMethod() { // 异步执行的代码 } // 使用自定义的TaskExecutor执行异步任务 public void executeAsync(Runnable task) { taskExecutor.execute(task); } }
请注意,如果你的
AsyncService
中的方法是通过接口定义的,并且你正在使用基于接口的代理(这是Spring AOP的默认行为),那么只有通过代理调用这些方法时,@Async
注解才会生效。这意味着,如果你从同一个类的另一个方法中调用带有@Async
注解的方法,它不会异步执行。 -
监控和调优:
你可以使用Spring Boot的Actuator模块来监控你的线程池。通过添加Actuator的依赖并启用相关端点,你可以查看线程池的实时状态,如当前线程数、活动线程数、任务队列大小等。这有助于你根据应用程序的实际需求调整线程池的配置。