1. 自定义线程池
1.1 引入属性配置文件提示坐标
<!-- spring的提示工具 添加该坐标这样在properties配置文件中就可以读取到并提示 @ConfigurationProperties 标注的配置类中的信息了-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
1.2 定义线程池参数配置类
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;
}
1.3 线程池配置类
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.*;
@Configuration
// @EnableConfigurationProperties(ThreadPoolConfigProperties.class)
// 通过EnableConfigurationProperties将ThreadPoolConfigProperties注入到容器
// 因为ThreadPoolConfigProperties添加了@Components,所以这里不需要添加@EnableConfigurationProperties(ThreadPoolConfigProperties.class)
// 如果ThreadPoolConfigProperties没有添加@Components注解,那么这里需要添加@EnableConfigurationProperties(ThreadPoolConfigProperties.class)
// 才能在方法上注入容器中的组件ThreadPoolConfigProperties
public class MyThreadPool {
@Bean
public ThreadPoolExecutor threadPoolExecutor(ThreadPoolConfigProperties config){
return new ThreadPoolExecutor(config.getCoreSize(),config.getMaxSize(),config.getKeepAliveTime(), TimeUnit.SECONDS,
new LinkedBlockingDeque<Runnable>(100000),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
}
}
1.4 配置文件
## 线程池参数配置
gulimall.thread.core-size=20
gulimall.thread.max-size=200
gulimall.thread.keep-alive-time=30
2. CompletableFuture使用
/*
* 查询详情
* */
@Override
public SkuItemVo item(Long skuId) throws ExecutionException, InterruptedException {
SkuItemVo vo = new SkuItemVo();
// 1. sku基本信息获取 sku_Info
CompletableFuture<SkuInfoEntity> infoFuture = CompletableFuture.supplyAsync(() -> {
SkuInfoEntity skuInfoEntity = this.getById(skuId);
vo.setInfo(skuInfoEntity);
return skuInfoEntity;
}, executor);
// 3 4 5 需要等待info执行完毕才能执行
CompletableFuture<Void> saleFuture = infoFuture.thenAcceptAsync(res -> {
if (null != res) {
Long spuId = res.getSpuId();
Long catalogId = res.getCatalogId();
// 3. 获取spu的销售属性组合
List<ItemSaleAttrVo> saleAttrVos = skuSaleAttrValueService.getSaleAttrsBySpuId(spuId);
vo.setSaleAttr(saleAttrVos);
}
}, executor);
CompletableFuture<Void> desFuture = infoFuture.thenAcceptAsync(res -> {
if (null != res) {
Long spuId = res.getSpuId();
Long catalogId = res.getCatalogId();
// 4. 获取spu介绍
SpuInfoDescEntity descEntity = descService.getById(spuId);
vo.setDesp(descEntity);
}
}, executor);
CompletableFuture<Void> groupsFuture = infoFuture.thenAcceptAsync(res -> {
if (null != res) {
Long spuId = res.getSpuId();
Long catalogId = res.getCatalogId();
// 5.获取spu的规格参数信息
List<spuItemAttrGroupVo> attrGroupVos = attrGroupService.getAttrGroupWithAttrsBySpuId(spuId, catalogId);
vo.setGroupAttrs(attrGroupVos);
}
}, executor);
// 2. sku图片信息 sku_images 独立的线程,不需要等待info执行完毕
CompletableFuture<Void> imagesFuture = CompletableFuture.runAsync(() -> {
List<SkuImagesEntity> skuImages = imagesService.list(new QueryWrapper<SkuImagesEntity>().eq("sku_id", skuId));
vo.setImages(skuImages);
}, executor);
// 等待所有任务结束 infoFuture可以不用写
CompletableFuture.allOf(imagesFuture,saleFuture,desFuture,groupsFuture).get();
return vo;
}