使用场景
应用中有两种不同类型的异步,产品的和订单的,在某一瞬间,大量涌入了订单的异步任务,这样,根据线程池的配置,订单的异步任务占满了线程池以后,就会影响产品的异步任务进入线程池,导致产品的功能异常。
解决办法
一个比较好的方案是:把产品和订单隔离开,使用两个独立的线程池,避免互相影响。
定义不同线程池
@Configuration
@EnableAsync
public class ThreadPoolConfig {
@Value("${myThreadPool.maxPoolSize}")
private Integer maxPoolSize;
@Value("${myThreadPool.queueCapacity}")
private Integer queueCapacity;
@Value("${myThreadPool.keepAliveSeconds}")
private Integer keepAliveSeconds;
@Value("${myThreadPool.waitForTasksToCompleteOnShutdown}")
private Boolean waitForTasksToCompleteOnShutdown;
@Bean("orderPool")
public Executor orderExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 设置核心线程数等于系统核数
int availableProcessors = Runtime.getRuntime().availableProcessors();
// 设置核心线程数
executor.setCorePoolSize(availableProcessors);
// executor.setCorePoolSize(corePoolSize);
// 设置最大线程数
executor.setMaxPoolSize(maxPoolSize);
// 设置队列大小
executor.setQueueCapacity(queueCapacity);
// 设置线程活跃时间(秒)
executor.setKeepAliveSeconds(keepAliveSeconds);
// 线程满了之后由调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 设置默认线程名称
executor.setThreadNamePrefix("threadPool");
// 等待所有任务执行完成后再关闭线程池
executor.setWaitForTasksToCompleteOnShutdown(waitForTasksToCompleteOnShutdown);
// 执行初始化
executor.initialize();
return executor;
}
@Bean("productPool")
public Executor productExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
int availableProcessors = Runtime.getRuntime().availableProcessors();
executor.setCorePoolSize(availableProcessors);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setKeepAliveSeconds(keepAliveSeconds);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setThreadNamePrefix("productPool");
executor.setWaitForTasksToCompleteOnShutdown(waitForTasksToCompleteOnShutdown);
executor.initialize();
return executor;
}
}
yml 配置内容如下
myThreadPool:
maxPoolSize: 20
queueCapacity: 2048
keepAliveSeconds: 60
waitForTasksToCompleteOnShutdown: true
定义服务类
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
@Async("orderPool")
@Override
public void getOrder() {
log.info("getOrder, current thread is {}",Thread.currentThread().getName());
}
}
@Service
@Slf4j
public class ProductServiceImpl implements ProductService {
@Async("productPool")
@Override
public void getProduct() {
log.info("getProduct, current thread is {}",Thread.currentThread().getName());
}
}
测试
@Test
public void multiPoolThreadTest() {
for (int i = 0; i < 10; i++) {
orderService.getOrder();
productService.getProduct();
}
}
测试结果如下