线程池参数-SpringBoot配置线程池
先线程池有几个核心的参数概念:
-
核心线程数(corePoolSize)
线程池中会维护一个最小的线程数量,即使这些线程处理空闲状态,他们也不会被销毁,除非设置了allowCoreThreadTimeOut。这里的最小线程数量即是corePoolSize。任务提交到线程池后,首先会检查当前线程数是否达到了corePoolSize,如果没有达到的话,则会创建一个新线程来处理这个任务。
-
最大线程数(maximumPoolSize)
当前线程数达到corePoolSize后,如果继续有任务被提交到线程池,会将任务缓存到工作队列(后面会介绍)中。如果队列也已满,则会去创建一个新线程来出来这个处理。线程池不会无限制的去创建新线程,它会有一个最大线程数量的限制,这个数量即由maximunPoolSize指定。
-
活跃时间/空闲线程存活时间(keepAliveTime)
一个线程如果处于空闲状态,并且当前的线程数量大于corePoolSize,那么在指定时间后,这个空闲线程会被销毁,这里的指定时间由keepAliveTime来设定
-
空闲线程存活时间的单位(unit)
是指空闲线程存活时间的单位。keepAliveTime的计量单位。枚举类型TimeUnit类。线程空闲时间的单位,可以是秒、毫秒等。
-
阻塞队列/线程工作队列(workQueue)
- ArrayBlockingQueue FIFO有界阻塞队列
- LinkedBlockingQueue FIFO无限队列
- SynchronousQueue不缓存任务的阻塞队列
- PriorityBlockingQueue具有优先级的无界阻塞队列,优先级通过参数Comparator实现。
-
线程工厂(threadFactory)
创建一个新线程时使用的工厂,可以用来设定线程名、是否为daemon线程等等,一般使用默认的ThreadFactory即可。
-
超出线程数和工作队列时候的任务请求处理策略/拒绝策略(handler)
当工作队列中的任务已到达最大限制,并且线程池中的线程数量也达到最大限制,这时如果有新任务提交进来,该如何处理呢。对新任务的处理策略,可以是抛出异常、丢弃任务等。这里的拒绝策略,就是解决这个问题的,jdk中提供了4中拒绝策略:
- 策略1:ThreadPoolExecutor.AbortPolicy(默认)拒绝执行
- 策略2:ThreadPoolExecutor.CallerRunsPolicy调用 execute 方法的线程本身运行任务
- 策略3:ThreadPoolExecutor.DiscardOldestPolicy执行程序未关闭,则删除工作队列头部的任务
- 策略4:ThreadPoolExecutor.DiscardPolicy无法执行的任务被简单地删除
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
原生使用
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3, 10, 30,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(4),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.DiscardOldestPolicy());
spring使用
配置文件
@Configuration
@EnableAsync
public class ThreadPoolConfig {
/**
* 下面的配置是配置Springboot的@Async注解所用的线程池
*/
@Bean("taskExecutor")
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 设置线程池核心容量
executor.setCorePoolSize(4);
// 设置线程池最大容量
executor.setMaxPoolSize(8);
// 设置任务队列长度
executor.setQueueCapacity(200);
// 设置线程超时时间
executor.setKeepAliveSeconds(60);
// 设置线程名称前缀
executor.setThreadNamePrefix("xyjAsyncPool-");
// 设置任务丢弃后的处理策略,当poolSize已达到maxPoolSize,如何处理新任务(是拒绝还是交由其它线程处理)
// CallerRunsPolicy: 不在新线程中执行任务,而是由调用者所在的线程来执
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
配置测试接口及其实现类
public interface TestAsync {
void doAsync();
}
@Service
@Slf4j
public class TestAsyncImpl implements TestAsync {
@Override
//使用@Async,并将前面的注册的bean,填写到Async的value中
@Async("taskExecutor")
public void doAsync() {
log.info("== async start==");
log.info("线程{}执行代码逻辑",Thread.currentThread().getName());
log.info("== async end==");
}
}
测试
@SpringBootTest
public class AsyncTest {
//引用类
@Autowired
private TestAsync testAsync;
@Test
void test(){
for (int i = 0; i < 10; i++) {
testAsync.doAsync();
}
}
}
结果
2023-01-29 16:47:12.491 INFO 13332 --- [ taskExecutor-1] c.w.a.service.async.impl.TestAsyncImpl : == async start==
2023-01-29 16:47:12.491 INFO 13332 --- [ taskExecutor-3] c.w.a.service.async.impl.TestAsyncImpl : == async start==
2023-01-29 16:47:12.493 INFO 13332 --- [ taskExecutor-5] c.w.a.service.async.impl.TestAsyncImpl : == async start==
2023-01-29 16:47:12.493 INFO 13332 --- [ taskExecutor-6] c.w.a.service.async.impl.TestAsyncImpl : == async start==
2023-01-29 16:47:12.493 INFO 13332 --- [ taskExecutor-1] c.w.a.service.async.impl.TestAsyncImpl : == async start==
2023-01-29 16:47:12.501 INFO 13332 --- [ taskExecutor-9] c.w.a.service.async.impl.TestAsyncImpl : == async start==
2023-01-29 16:47:12.501 INFO 13332 --- [taskExecutor-10] c.w.a.service.async.impl.TestAsyncImpl : == async start==
2023-01-29 16:47:12.500 INFO 13332 --- [ taskExecutor-7] c.w.a.service.async.impl.TestAsyncImpl : == async start==
2023-01-29 16:47:12.502 INFO 13332 --- [ taskExecutor-8] c.w.a.service.async.impl.TestAsyncImpl : == async start==
2023-01-29 16:47:12.500 INFO 13332 --- [ taskExecutor-7] c.w.a.service.async.impl.TestAsyncImpl : == async start==
2023-01-29 16:47:12.502 INFO 13332 --- [ taskExecutor-6] c.w.a.service.async.impl.TestAsyncImpl : 线程taskExecutor-6执行代码逻辑
2023-01-29 16:47:12.501 INFO 13332 --- [ taskExecutor-8] c.w.a.service.async.impl.TestAsyncImpl : 线程taskExecutor-8执行代码逻辑
2023-01-29 16:47:12.503 INFO 13332 --- [ taskExecutor-5] c.w.a.service.async.impl.TestAsyncImpl : == async end==
2023-01-29 16:47:12.492 INFO 13332 --- [ taskExecutor-9] c.w.a.service.async.impl.TestAsyncImpl : 线程taskExecutor-9执行代码逻辑
2023-01-29 16:47:12.503 INFO 13332 --- [ taskExecutor-2] c.w.a.service.async.impl.TestAsyncImpl : == async end==
2023-01-29 16:47:12.503 INFO 13332 --- [ taskExecutor-7] c.w.a.service.async.impl.TestAsyncImpl : == async end==
2023-01-29 16:47:12.501 INFO 13332 --- [ taskExecutor-9] c.w.a.service.async.impl.TestAsyncImpl : 线程taskExecutor-9执行代码逻辑
2023-01-29 16:47:12.492 INFO 13332 --- [ taskExecutor-1] c.w.a.service.async.impl.TestAsyncImpl : 线程taskExecutor-1执行代码逻辑
2023-01-29 16:47:12.506 INFO 13332 --- [ taskExecutor-1] c.w.a.service.async.impl.TestAsyncImpl : == async end==
2023-01-29 16:47:12.506 INFO 13332 --- [ taskExecutor-9] c.w.a.service.async.impl.TestAsyncImpl : == async end==
2023-01-29 16:47:12.493 INFO 13332 --- [ taskExecutor-3] c.w.a.service.async.impl.TestAsyncImpl : 线程taskExecutor-3执行代码逻辑
2023-01-29 16:47:12.501 INFO 13332 --- [taskExecutor-10] c.w.a.service.async.impl.TestAsyncImpl : 线程taskExecutor-10执行代码逻辑
2023-01-29 16:47:12.506 INFO 13332 --- [ taskExecutor-3] c.w.a.service.async.impl.TestAsyncImpl : == async end==
2023-01-29 16:47:12.506 INFO 13332 --- [taskExecutor-10] c.w.a.service.async.impl.TestAsyncImpl : == async end==
2023-01-29 16:47:12.502 INFO 13332 --- [ taskExecutor-8] c.w.a.service.async.impl.TestAsyncImpl : 线程taskExecutor-8执行代码逻辑
2023-01-29 16:47:12.506 INFO 13332 --- [ taskExecutor-8] c.w.a.service.async.impl.TestAsyncImpl : == async end==
2023-01-29 16:47:12.502 INFO 13332 --- [ taskExecutor-7] c.w.a.service.async.impl.TestAsyncImpl : 线程taskExecutor-7执行代码逻辑
2023-01-29 16:47:12.508 INFO 13332 --- [ taskExecutor-7] c.w.a.service.async.impl.TestAsyncImpl : == async end==
2023-01-29 16:47:12.493 INFO 13332 --- [ taskExecutor-4] c.w.a.service.async.impl.TestAsyncImpl : 线程taskExecutor-4执行代码逻辑
2023-01-29 16:47:12.508 INFO 13332 --- [ taskExecutor-4] c.w.a.service.async.impl.TestAsyncImpl : == async end==