Bootstrap

线程池异步编排

package com.ray.test;

import com.alibaba.fastjson.TypeReference;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadTest {

    public static ExecutorService executor = Executors.newFixedThreadPool(10);

    /**
     * 异步编排、任务组合
     */
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("主线程开始:"+Thread.currentThread().getName());
        ThreadTest test = new ThreadTest();
        test.fun4();
        System.out.println("主线程结束:"+Thread.currentThread().getName());
    }

    //有、无返回值
    public  void fun1() throws ExecutionException, InterruptedException {
        //异步编排 无返回值
        CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {
            System.out.println("当前线程:"+Thread.currentThread().getName());
            int i = 10 / 2;
            System.out.println("结果运行:" + i);
        }, executor);

        //有返回值
        CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程:" + Thread.currentThread().getName());
            int i = 10 / 2;
            System.out.println("结果运行:" + i);
            return i;
        }, executor).exceptionally(throwable -> {
            //处理异常
            return 10;
        });
        System.out.println(future2.get());

        //有返回值,handle处理结果
        CompletableFuture<Integer> future3 = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程:" + Thread.currentThread().getName());
            int i = 10 / 2;
            System.out.println("结果运行:" + i);
            return i;
        }, executor).handle((result, throwable) -> {
            if(result != null){
                return result * 2;
            }
            if(throwable != null){
                return 20;
            }
            return result;
        });
        System.out.println(future3.get()+"--future3");

    }

    /**
     * 串行化 A执行后 -》 B执行
     * 带Async的意思是:再开一个线程; 否则和A线程共用一个线程(测试出来是主线程)
     */
    public void fun2() throws ExecutionException, InterruptedException {
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程:" + Thread.currentThread().getName());
            int i = 10 / 2;
            return i;
        }, executor).thenAccept(result -> {
            System.out.println("--当前线程:" + Thread.currentThread().getName());
            System.out.println("thenAcceptAsync 获取上一步结果,无返回值,result:" + result);
        }).thenRunAsync(() -> {
            System.out.println("--当前线程:" + Thread.currentThread().getName());
            System.out.println("thenRunAsync 无结果,无返回值");
        }, executor).thenApplyAsync((result) -> {
            return result + "haha:thenApplyAsync获取返回值并处理返回";
        }, executor);
        System.out.println(future2.get());
    }

    /**
     * 多任务组合
     */
    public void fun4() throws ExecutionException, InterruptedException {
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("查询商品的图片信息……");
            return "hello.jpg";
        }, executor);
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("查询商品的属性……");
            return "黑色 2+64G";
        }, executor);
        CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(3000);
                System.out.println("查询商品的介绍……");//模拟业务时间超长
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "apple";
        }, executor);

        //allOf所有执行完后执行
        CompletableFuture<Void> future4 = CompletableFuture.allOf(future1, future2, future3);
        future4.get();
        System.out.println(future1.get() + future2.get() + future3.get());

        //anyOf() 只要一个任务,结束就可以继续执行
//        CompletableFuture<Object> future4_5 = CompletableFuture.anyOf(future1, future2, future3);
//        System.out.println(Thread.currentThread().getName()+":当前线程");
//        future4_5.get();//等待所有任务完成 可以打印
//        System.out.println(future4_5.get());
    }

    /**
     * 本方法需要异步编排处理
     * 1 2 没关系 查谁都行
     * 3 4 5 必须依赖 1(1 -> 3、4、5)
     * 3 4 5 是并列的,得等 1 完成
     * 2 又和 1 没关系
     */
    public void item(Long skuId) throws ExecutionException, InterruptedException {

        //要返回给前端的大对象
        SkuItemVo skuItemVo = new SkuItemVo();

        CompletableFuture<SkuInfoEntity> infoFuture = CompletableFuture.supplyAsync(() -> {
            //1 sku基本信息获取 pms_sku_info
            SkuInfoEntity info = getById(skuId);
            skuItemVo.setInfo(info);
            return info;
        }, executor);

        CompletableFuture<Void> saleAttrFuture = infoFuture.thenAcceptAsync((result) -> {
            //3 spu的销售属性组合
            Long spuId = result.getSpuId();
            List<SkuItemSaleAttrVo> saleAttrVos = skuSaleAttrValueService.getSaleAttrBySpuId(spuId);
            skuItemVo.setSaleAttr(saleAttrVos);
        }, executor);

        CompletableFuture<Void> descFuture = infoFuture.thenAcceptAsync((result) -> {
            //4 spu的介绍 pms_spu_info_desc
            Long spuId = result.getSpuId();
            SpuInfoDescEntity desc = spuInfoDescService.getById(spuId);
            skuItemVo.setDesc(desc);
        }, executor);

        CompletableFuture<Void> baseFuture = infoFuture.thenAcceptAsync((result) -> {
            //5 spu的规格参数信息
            Long spuId = result.getSpuId();
            Long catalogId = result.getCatalogId();
            List<SpuItemAttrGroupVo> attrGroupVos = attrGroupService.getAttrGroupWithAttrsBySpuId(spuId, catalogId);
            skuItemVo.setGroupAttrs(attrGroupVos);
        }, executor);


        CompletableFuture<Void> imagesFuture = CompletableFuture.runAsync(() -> {
            //2 sku图片信息 pms_sku_images
            List<SkuImagesEntity> images = skuImagesService.getImagesBySkuId(skuId);
            skuItemVo.setImages(images);
        }, executor);

        CompletableFuture<Void> seckillFuture = CompletableFuture.runAsync(() -> {
            //查询当前sku是否参加秒杀优惠
            R r = seckillFeignService.getSkuSeckillInfo(skuId);
            if (r.getCode() == 0) {
                SeckillSkuInfoVo seckillSkuRedisVo = r.getData(new TypeReference<SeckillSkuInfoVo>() {
                });
                skuItemVo.setSeckillSkuInfoVo(seckillSkuRedisVo);
            }
        }, executor);

        //异步编排 - 阻塞等结果
        //等待所有1 2 3 4 5任务都完成 infoFuture可以省略
        CompletableFuture.allOf(saleAttrFuture, descFuture, baseFuture, imagesFuture, seckillFuture).get();

        return skuItemVo;
    }

    /**
     * 两个任务组合
     */
    public void fun3() throws ExecutionException, InterruptedException {
        CompletableFuture<Object> future3_1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务1开始。当前线程:" + Thread.currentThread().getId());
            int i = 10 / 4;
            System.out.println("任务1结束。结果运行:" + i);
            return i;
        }, executor);
        CompletableFuture<Object> future3_2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务2开始。当前线程:" + Thread.currentThread().getId());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("任务2结束...");
            return "hello";
        }, executor);

        //runAfterBothAsync()不能感知前两步的执行结果 自己也没有返回值
        future3_1.runAfterBothAsync(future3_2, ()->{
            System.out.println("任务3开始。当前线程:" + Thread.currentThread().getId());
        }, executor);

        //thenAcceptBothAsync()能感知前两步的执行结果 自己没有返回值
        future3_1.thenAcceptBothAsync(future3_2, (f1, f2)->{
            System.out.println("任务3开始。之前的结果:f1=" + f1 + ";f2=" + f2);
        }, executor);

        //thenCombineAsync()能感知前两步的执行结果, 还能处理前面两个任务的返回值,并生成返回值 自己有返回值
        CompletableFuture<String> future3_3 = future3_1.thenCombineAsync(future3_2, (f1, f2) -> {
            return f1 + ": " + f2 + "->ww";
        }, executor);
        System.out.println(future3_3.get());

        /**
         * 两个任务 只要有一个完成就行 就能执行第三个任务 A || B = C
         */
        //runAfterEitherAsync() 不感知前面任务的结果,自己也没有返回值
        future3_1.runAfterEitherAsync(future3_2, () -> {
            System.out.println("任务3开始执行。");
        }, executor);

        //acceptEitherAsync() 能感知前面任务的结果,自己没有返回值
        future3_1.acceptEitherAsync(future3_2, (result) -> {//要求任务1、2的返回类型必须相同
            System.out.println("任务3开始执行。" + result);
        }, executor);

        //applyToEitherAsync() 能感知前面任务的结果,自己有返回值
        CompletableFuture<String> future3_4 = future3_1.applyToEitherAsync(future3_2, (result) -> {//要求任务1、2的返回类型必须相同
            System.out.println("任务3开始执行。" + result);
            return result.toString() + "哈哈";
        }, executor);
        System.out.println(future3_4.get());
    }




}

;