线程池的异步编排的使用
CompletableFuture 异步编排笔记
一. 介绍
使用线程池可以解决多线程的异步操作,优化线程。如果多线程有关系、顺序, 使用 CompletableFuture 异步编排可以优化线程的异步操作,加快请求的速度。
二、写配置类
1).写依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
2).写线程池的的属性配置
@ConfigurationProperties(prefix = "gulimall.thread")
@Configuration
@Data
public class ThreadPoolConfigProperties {
private Integer coreSize;
private Integer maxSize;
private Integer keepAliveTime;
}
3).配置文件 配置线程池的参数值–application.properties
#线程池 参数的配置
gulimall.thread.core-size=20
gulimall.thread.max-size=200
gulimall.thread.keep-alive-time=10
4).线程池的配置类
//线程池配置类
//@EnableConfigurationProperties(ThreadPoolConfigProperties.class)//有了@Component就不用此注解了
@Configuration
public class MyThreadConfig {
@Bean
public ThreadPoolExecutor ehreadPoolExecutor(ThreadPoolConfigProperties pool){
return new ThreadPoolExecutor(
pool.getCoreSize(),
pool.getMaxSize(),
pool.getKeepAliveTime(),
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(),
new ThreadPoolExecutor.AbortPolicy());//丢弃策略
}
}
二、异步编排的使用(优化商品详情信息的获取)
1).介绍–业务依赖关系
因为3、4、5需要1的结果才能获得spuId,所以3、4、5与1是依赖关系(顺序);2不需要,skuId参数有提供(所以不用依赖、顺序)
2).代码
2.1).注入ThreadPoolExecutor(我的使用autowired)
@Autowired
ThreadPoolExecutor executor;
或者
@Resource
private ThreadPoolExecutor executor;
注意:ThreadPoolExecutor 为 import java.util.concurrent.ThreadPoolExecutor;
2.2).实现类代码
//展示当前sku商品详情
@Override
public SkuItemVo item(Long skuId) {
SkuItemVo skuItemVo = new SkuItemVo();
CompletableFuture<SkuInfoEntity> infoFuture = CompletableFuture.supplyAsync(() -> {
//1.sku基本信息,pms_spu_info
SkuInfoEntity info = getById(skuId);
skuItemVo.setInfo(info);
return info;
}, executor);
//因为3、4、5需要1的结果才能获得spuId,所以3、4、5与1是依赖关系(顺序);2不需要(所以不用依赖、顺序)
CompletableFuture<Void> saleAttrFuture = infoFuture.thenAcceptAsync((res) -> {
//3.spu销售属性组合,(3与1是依赖关系)
List<SkuItemSaleAttrVo> saleAttrVos = skuSaleAttrValueService.getSkuSaleAttrsBySpuId(res.getSpuId());
skuItemVo.setSaleAttr(saleAttrVos);
}, executor);
CompletableFuture<Void> descFuture = infoFuture.thenAcceptAsync((res) -> {
//4.spu的介绍,pms_spu_info_desc(4与1是依赖关系)
SpuInfoDescEntity spuInfoDesc = spuInfoDescService.getById(res.getSpuId());
skuItemVo.setDesp(spuInfoDesc);
}, executor);
CompletableFuture<Void> baseAttrFuture = infoFuture.thenAcceptAsync((res) -> {
//5.spu规格参数,(5与1是依赖关系)
List<SpuItemAttrGroupVo> attrGroups = attrGroupService.getAttrGroupWithAttrsBySpuId(res.getSpuId(), res.getCatalogId());
skuItemVo.setGroupAttrs(attrGroups);
}, executor);
CompletableFuture<Void> imageFuture = CompletableFuture.runAsync(() -> {
//2.sku图片信息,pms_sku_images(2与1没有任何关系,直接可以获得)
List<SkuImagesEntity> images = skuImagesService.getImagesBySkuId(skuId);
skuItemVo.setImages(images);
}, executor);
//所有完成后,任务才成功
CompletableFuture<Void> allOf = CompletableFuture.allOf(infoFuture, saleAttrFuture, descFuture, baseAttrFuture, imageFuture);
try {
allOf.get();
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("获取商品详情有异常!!");
} catch (ExecutionException e) {
e.printStackTrace();
}
return skuItemVo;
}
2.3).结果描述。
提供线程池的异步编排,实现线程的异步操作,实现线程间关系、顺序的操作,真正实现异步、线程优化
问题–实现类注入ThreadPoolExecutor失败
Field executor in com.atguigu.gulimall.product.service.impl.SkuInfoServiceImpl required a bean of type ‘org.apache.tomcat.util.threads.ThreadPoolExecutor’ that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type ‘org.apache.tomcat.util.threads.ThreadPoolExecutor’ in your configuration.
错误原因@Autowired注入线程池依赖 导入错误
@Autowired
ThreadPoolExecutor executor;
ThreadPoolExecutor 为 import java.util.concurrent.ThreadPoolExecutor;