前提知识
创建线程的几种方式
1.继承Thread
Thread01 thread01 = new Thread01();
thread01.start();//启动线程
2.实现Runnable接口
new Thread(new Runable01()).start();
3.实现Callable接口+FutureTask(可以拿到返回结果,可以处理异常)
FutureTask<Integer> futureTask = new FutureTask<>(new Callable01());
new Thread(futureTask).start();
//阻塞等待整个线程执行完成,获取返回结果
Integer integer = futureTask.get();
4.线程池
给线程池提交任务
ExecutorService executorService = Executors.newFixedThreadPool(10);
executorService.execute(new Runable01());
记住!
生产实践中是使用自定义线程池! 由公司的架构师负责设计好的。
一、配置线程池
在config包下配置
@ConfigurationProperties(prefix = "mall.thread")
@Component
@Data
public class ThreadPoolConfigProperties {
private Integer corePoolSize;
private Integer maxSize;
private Integer keepAliveTime;
}
可以application.yml配置线程池参数
# 线程池的配置
mall:
thread:
max-size: 200
keep-alive-time: 10
core-pool-size: 20
将线程池注入容器
@Configuration
public class MyThreadConfig {
@Bean
public ThreadPoolExecutor threadPoolExecutor(ThreadPoolConfigProperties pool) {
return new ThreadPoolExecutor(pool.getCorePoolSize(),
pool.getMaxSize(),
pool.getKeepAliveTime(),
TimeUnit.SECONDS,
new LinkedBlockingDeque<>(100000),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.DiscardPolicy());
}
}
实战任务
- sku基本信息获取 pms_sku_info
- sku的图片信息 pms_sku_images
- 获取spu的销售属性组合
- 获取spu的介绍 pms_spu_info_desc
- 获取spu的规格参数信息
1和2可以同时异步执行,3,4,5要等1的返回结果。1,2,3,4,5都完成才能返回总结果。
异步实现
CompletableFuture组合式异步编程
runAsync 和 supplyAsync方法
CompletableFuture 提供了四个静态方法来创建一个异步操作。
public static CompletableFuture<Void> runAsync(Runnable runnable)
public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor)
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor)
没有指定Executor的方法会使用ForkJoinPool.commonPool() 作为它的线程池执行异步代码。如果指定线程池,则使用指定的线程池运行。以下所有的方法都类同。
- runAsync方法不支持返回值。
- supplyAsync可以支持返回值。
实现代码
@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 info = getById(skuId);
skuItemVo.setInfo(info);
Long spuId = info.getSpuId();
Long catalogId = info.getCatalogId();
return info;
}, executor);
//thenAcceptAsync能接受上一步结果,但是无返回值
CompletableFuture<Void> saleAttrFuture = infoFuture.thenAcceptAsync((res) -> {
//3.获取spu的销售属性组合
List<SkuItemSaleAttrVo> saleAttrVos = skuSaleAttrValueService.getSaleAttrsBySpuId(res.getSpuId());
skuItemVo.setSaleAttr(saleAttrVos);
}, executor);
//thenAcceptAsync能接受上一步结果,但是无返回值
CompletableFuture<Void> descFuture = infoFuture.thenAcceptAsync((res) -> {
//4.获取spu的介绍 pms_spu_info_desc
SpuInfoDescEntity spuInfoDescEntity = spuInfoDescService.getById(res.getSpuId());
skuItemVo.setDesp(spuInfoDescEntity);
}, executor);
//thenAcceptAsync能接受上一步结果,但是无返回值
CompletableFuture<Void> baseAttrFuture = infoFuture.thenAcceptAsync((res) -> {
//5.获取spu的规格参数信息
List<SpuItemAttrGroupVo> attrGroupVos = attrGroupService.getAttrGroupWithAttrsBySpuId(res.getSpuId(), res.getCatalogId());
skuItemVo.setGroupAttrs(attrGroupVos);
}, executor);
//runAsync 无返回值
CompletableFuture<Void> imageFuture = CompletableFuture.runAsync(() -> {
//2.sku的图片信息 pms_sku_images
List<SkuImagesEntity> images = skuimagesService.getImagesBySkuId(skuId);
skuItemVo.setImages(images);
}, executor);
//等待所有任务都完成
CompletableFuture.allOf(saleAttrFuture, descFuture, baseAttrFuture, imageFuture).get();
return skuItemVo;
}