SpringBoot⾃定义线程池
使⽤SpringBoot构建应⽤时,如何使⽤线程处理异步任务?其实springBoot已经提供了默认的实现,通过在启动类上加上注解
@EnableAsync, 然后在需要异步处理的⽅法上增加注解@Async即可启动⼀个线程进⾏异步处理。其实质类似于:new Thread(()-{System.out.print("处理异步任务")}).start()。但需要注意的是@Async默认使⽤的是SimpleAsyncTaskExecutor,每次提交任务都创建线程,要⼩⼼在使⽤⼤任务的场景下创建⼤量线程导致OOM异常。所以,还是⾃定义线程池好。⾃定义线程池有2种实现⽅式。
1. ⾃定义线程池,然后使⽤⾃⼰定义的线程池
1.1 修改l⽂件,增加线程池的配置参数,如下
1.2 线程池配置属性类MyThreadPoolConfig .java
/**
* 线程池配置属性类
*/
@ConfigurationProperties(prefix = "mytask.pool")
public class MyThreadPoolConfig {
private int corePoolSize;
private int maxPoolSize;
private int keepAliveSeconds;
private int queueCapacity;
}
1.3 启动类上⼀定要开启线程异步⽀持:@EnableAsync
@EnableAsync
@EnableConfigurationProperties({MyThreadPoolConfig.class})
@SpringCloudApplication
public class application
{
public static void main(String[] args)
{
SpringApplication.run(application.class, args);
}
}
1.4 创建⾃⼰的线程池
/**
* 创建线程池
*/
@Configuration
public class MyTaskExecutePool {
@Autowired
private MyThreadPoolConfig config;
@Bean("myTaskPool")
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
/
/核⼼线程池⼤⼩
executor.CorePoolSize());
//最⼤线程数
executor.MaxPoolSize());
//队列容量
executor.QueueCapacity());
//活跃时间
executor.KeepAliveSeconds());
//线程名字前缀
executor.setThreadNamePrefix("TaskExecutePool-");
// setRejectedExecutionHandler:当pool已经达到maxSize的时候,如何处理新进任务
/
/ CallerRunsPolicy:不在新线程中执⾏任务,⽽是由调⽤者所在的线程来执⾏
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 等待所有任务结束后再关闭线程池
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.initialize();
return executor;
}
}
需要注意的是这样定义的线程池在使⽤的时候要在@Async主键⾥指定名称,如:@Async("mytaskExecutor"), 否则会使⽤spingtBoot提供的默认线程池。
2. 重新spring默认的线程池
第⼀种⽅式创建的线程池在使⽤的时候必须要指明异步任务要使⽤的线程池名称,⽽重新srping默认的线程池,则不需要指定名称,直接写@Asyncj即可。
配置⽅式和⽅式⼀类似,唯⼀的区别在于配置类要实现AsyncConfigurer
/**
* 重新SpringBoot默认的线程池
springcloud和springboot*/
@Configuration
public class OverrideAsyncTaskExecutePool implements AsyncConfigurer{
//注⼊配置类
@Autowired
MyThreadPoolConfig config;
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//核⼼线程池⼤⼩
executor.CorePoolSize());
//最⼤线程数
executor.MaxPoolSize());
//队列容量
executor.QueueCapacity());
//活跃时间
executor.KeepAliveSeconds());
//线程名字前缀
executor.setThreadNamePrefix("MyExecutor-");
// setRejectedExecutionHandler:当pool已经达到max size的时候,如何处理新任务
// CallerRunsPolicy:不在新线程中执⾏任务,⽽是由调⽤者所在的线程来执⾏
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论