现在我想取得商品的详细信息,但是商品的信息需要从不同的地方取得,在没有进行优化前,程序需要一步一步完成五步操作,但是使用多线程后,所花费的时间就可能大大缩短。而这里就考虑到用Java8新引入的CompletableFuture来进行优化。
进行异步优化前:
@Override
public SkuItemVo item(Long skuId) {
SkuItemVo skuItemVo = new SkuItemVo();
//1.sku基本信息获取 pms_sku_info
SkuInfoEntity infoEntity = getById(skuId);
skuItemVo.setInfo(infoEntity);
Long catalogId = infoEntity.getCatalogId();
Long spuId = infoEntity.getSpuId();
//2.sku的图片信息 pms_sku_images
List<SkuImagesEntity> imagesEntities = skuImagesService.getImagesBySkuId(skuId);
skuItemVo.setImages(imagesEntities);
//3.获取spu的销售属性组合
List<SkuItemSaleAttrVo> saleAttrVos =skuSaleAttrValueService.getSaleAttrsBySpuId(spuId);
skuItemVo.setSaleAttr(saleAttrVos);
//4.获取spu的介绍 pms_spu_info_desc
SpuInfoDescEntity spuInfo = spuInfoDescService.getById(spuId);
skuItemVo.setDesc(spuInfo);
//5.获取spu的规格参数信息
List<SpuItemAttrGroupVo> list = attrGroupService.getAttrGroupWithAttrsBySpuId(spuId,catalogId);
skuItemVo.setGroupAttrs(list);
return skuItemVo;
}
进行异步优化:
1.pom中导入:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
2.创建ThreadPoolConfigProperties,用于开发者自由配置线程池相关参数
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = "gulimall.thread")
@Component
@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.创建MyThreadConfig,配置线程池
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@Configuration
public class MyThreadConfig {
@Bean
public ThreadPoolExecutor threadPoolExecutor(ThreadPoolConfigProperties pool){
return new ThreadPoolExecutor(pool.getCoreSize(),pool.getMaxSize(),pool.getKeepAliveTime(), TimeUnit.SECONDS,
new LinkedBlockingDeque<>(100000), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
}
}
5.正式对一开始的item方法进行优化:
@Autowired
ThreadPoolExecutor executor;
@Override
public SkuItemVo item(Long skuId) throws ExecutionException, InterruptedException {
SkuItemVo skuItemVo = new SkuItemVo();
//创建异步对象,supplyAsync方法有返回值
CompletableFuture<SkuInfoEntity> infoFuture = CompletableFuture.supplyAsync(()->{
//1.sku基本信息获取 pms_sku_info
SkuInfoEntity infoEntity = getById(skuId);
skuItemVo.setInfo(infoEntity);
return infoEntity;
},executor);
//消费处理结果。接收任务的处理结果,并消费处理,无返回结果。
CompletableFuture<Void> saleAttrFuture = infoFuture.thenAcceptAsync((result) -> {
//3.获取spu的销售属性组合
List<SkuItemSaleAttrVo> saleAttrVos = skuSaleAttrValueService.getSaleAttrsBySpuId(result.getSpuId());
skuItemVo.setSaleAttr(saleAttrVos);
}, executor);
//消费处理结果。接收任务的处理结果,并消费处理,无返回结果。
CompletableFuture<Void> descFuture = infoFuture.thenAcceptAsync((result) -> {
//4.获取spu的介绍 pms_spu_info_desc
SpuInfoDescEntity spuInfo = spuInfoDescService.getById(result.getSpuId());
skuItemVo.setDesc(spuInfo);
}, executor);
//消费处理结果。接收任务的处理结果,并消费处理,无返回结果。
CompletableFuture<Void> baseAttrFuture = infoFuture.thenAcceptAsync((result) -> {
//5.获取spu的规格参数信息
List<SpuItemAttrGroupVo> list = attrGroupService.getAttrGroupWithAttrsBySpuId(result.getSpuId(), result.getCatalogId());
skuItemVo.setGroupAttrs(list);
}, executor);
//runAsync方法无返回值
CompletableFuture<Void> imageFuture = CompletableFuture.runAsync(() -> {
//2.sku的图片信息 pms_sku_images
List<SkuImagesEntity> imagesEntities = skuImagesService.getImagesBySkuId(skuId);
skuItemVo.setImages(imagesEntities);
}, executor);
//等待所有任务都完成
CompletableFuture.allOf(infoFuture,saleAttrFuture,descFuture,baseAttrFuture,imageFuture).get();
return skuItemVo;
}