CompletableFuture的使用

1、开启子线程并获取子线程结果
  @Test
    public void test1() {
        SmallTool.printTimeAndThread("媳妇进入餐厅");
        SmallTool.printTimeAndThread("媳妇点饭, 蛋炒饭 + 米饭");
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            SmallTool.printTimeAndThread("厨师炒菜");
            SmallTool.sleepMillis(200);
            SmallTool.printTimeAndThread("厨师盛饭");
            SmallTool.sleepMillis(200);
            return "饭做好了";
        });
        SmallTool.printTimeAndThread("媳妇在玩手机");
        SmallTool.printTimeAndThread(String.format("%s, 媳妇开吃",future.join()));
    }

2、thenCompose:连接两个异步任务(第一个异步任务完成后执行第二个异步任务),返回一个新的CompletableFuture

  @Test
    public void test2() {
        SmallTool.printTimeAndThread("媳妇进入餐厅");
        SmallTool.printTimeAndThread("媳妇点饭, 蛋炒饭 + 米饭");
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            SmallTool.printTimeAndThread("厨师炒菜");
            SmallTool.sleepMillis(200);
            return "饭做好了";
        }).thenCompose(res -> CompletableFuture.supplyAsync(() -> { //厨师炒完菜服务员才端饭
            SmallTool.printTimeAndThread(res);
            SmallTool.printTimeAndThread("服务员端饭");
            SmallTool.sleepMillis(200);
            return "饭盛好了";
        }));
        SmallTool.printTimeAndThread("媳妇在玩手机");
        SmallTool.printTimeAndThread(String.format("%s, 媳妇开吃",future.join()));
    }

3、thenApply:连接两个异步任务(第一个异步任务完成后执行第二个异步任务),返回的是同一个CompletableFuture,但CompletableFuture的数据类型可以改变

    @Test
    public void test22() {
        SmallTool.printTimeAndThread("媳妇进入餐厅");
        SmallTool.printTimeAndThread("媳妇点饭, 蛋炒饭 + 米饭");
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            SmallTool.printTimeAndThread("厨师炒菜");
            SmallTool.sleepMillis(200);
            return "1";
        }).thenApply(s -> {
            return s.equals("1")?"饭做好了":"饭没做好";
        });
        SmallTool.printTimeAndThread("媳妇在玩手机");
        SmallTool.printTimeAndThread(String.format("%s, 媳妇开吃",future.join()));
    }

4、thenCombine:两个异步任务并行执行

  @Test
    public void test3() {
        SmallTool.printTimeAndThread("媳妇进入餐厅");
        SmallTool.printTimeAndThread("媳妇点饭, 蛋炒饭 + 米饭");
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            SmallTool.printTimeAndThread("厨师炒菜");
            SmallTool.sleepMillis(200);
            return "菜做好了";
        }).thenCombine(CompletableFuture.supplyAsync(() -> { //炒菜和做饭同时进行
            SmallTool.sleepMillis(200);
            return "米饭做好了";
        }), (r1, r2) -> {
            SmallTool.printTimeAndThread("服务员端饭");
            SmallTool.sleepMillis(200);
            return String.format("%s和%s做好了", r1, r2);
        });
        SmallTool.printTimeAndThread("媳妇在玩手机");
        SmallTool.printTimeAndThread(String.format("%s, 媳妇开吃",future.join()));
    }

5、appltToEither:两个异步任务只有有一个执行完毕。exceptionally:异步任务中发送异常时执行

  @Test
    public void test5() {
        SmallTool.printTimeAndThread("小白吃完饭打车");
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            SmallTool.printTimeAndThread("700路公交车来了");
            SmallTool.sleepMillis(200);
            return "700路公交";
        }).applyToEither(CompletableFuture.supplyAsync(() -> {
            SmallTool.printTimeAndThread("800路公交车来了");
            SmallTool.sleepMillis(200);
            return "800路公交";
        }), firstComeBus -> {
            if(firstComeBus.startsWith("700")) {
                throw new RuntimeException("撞树上了");
            }
            return firstComeBus;
        }).exceptionally(e -> {
            SmallTool.printTimeAndThread("小白叫出租车");
            SmallTool.sleepMillis(200);
            return "出租车 叫到了";
        });
        SmallTool.printTimeAndThread(String.format("%s",future.join()));
    }

6、allOf:等待所有CompletableFuture执行完毕

@Test
    public void test8() {
        System.out.println(Runtime.getRuntime().availableProcessors());//获取计算机可用线程数
     //System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "10"); 设置自定义线程最大线程数
        //查看当前线程数
        System.out.println(ForkJoinPool.commonPool().getPoolSize());
        //查看最大线程数
        System.out.println(ForkJoinPool.getCommonPoolParallelism());
        SmallTool.printTimeAndThread("小白和小伙伴们 进餐厅点餐");
        long l = System.currentTimeMillis();
       /* ArrayList<Dish> dishes = new ArrayList<>();
        //点菜
        for(int i = 1; i <= 10; i++) {
            Dish dish = new Dish("菜" + i, 1);
            dishes.add(dish);
        }
        ArrayList<CompletableFuture> completableFutures = new ArrayList<>();
        //做菜
        for (Dish dish : dishes) {
            CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(dish::make);
            completableFutures.add(completableFuture);
        }
        //等待所有异步任务执行完毕
        CompletableFuture[] array = completableFutures.toArray(new CompletableFuture[completableFutures.size()]);*/

        //Stream方式实现
        CompletableFuture[] array = IntStream.rangeClosed(1, 10) //大于当前电脑线程数会超过2秒
                .mapToObj(i -> new Dish("菜" + i, 1))
                .map(dish -> CompletableFuture.runAsync(dish::makeUseCPU))
                .toArray(CompletableFuture[]::new);

        CompletableFuture<Void> completableFuture = CompletableFuture.allOf(array);
        completableFuture.join();
        SmallTool.printTimeAndThread("菜做好了, 上桌 " + (System.currentTimeMillis() - l));
    }

 

SmallTool工具类

public class SmallTool {
    public static void sleepMillis(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void printTimeAndThread(String tag) {
        String s = new StringJoiner("\t|\t")
                .add(String.valueOf(System.currentTimeMillis()))
                .add(String.valueOf(Thread.currentThread().getId()))
                .add(Thread.currentThread().getName())
                .add(tag)
                .toString();
        System.out.println(s);
    }
}

Dish类

public class Dish {
    //菜名
    private String name;
    //制作时长
    private Integer productionTime;

    public Dish(String name, Integer productionTime) {
        this.name = name;
        this.productionTime = productionTime;
    }

    public void make() {
        SmallTool.sleepMillis(TimeUnit.SECONDS.toMillis(this.productionTime));
        SmallTool.printTimeAndThread(this.name + " 制作完毕,来吃我把");
    }

    public void makeUseCPU() {
        SmallTool.printTimeAndThread(this.name + " 制作完毕,来吃我把" + compute());
    }

    private static long compute() { //当前电脑计算时间为1秒左右
        long l = System.currentTimeMillis();
        long result = 0;
        for(int i = 0; i < Integer.MAX_VALUE / 3; i++) {
            result += i * i % 3;
        }
        return System.currentTimeMillis() - l;
    }

    public static void main(String[] args) {
        System.out.println(compute());
    }
}

最后 ArrayList转数组的方法

     // 创建一个动态数组
        ArrayList<String> sites = new ArrayList<>();

        sites.add("Runoob");
        sites.add("Google");
        sites.add("Wiki");
        sites.add("Taobao");
    //默认转换为Object类型
    
Object[] objects = sites.toArray();
    // 转换成想要的类型
    String[] strings = sites.toArray(new String[sites.size()]);
    
    //分开写就是把list写入一个新的arr中

    String[] arr = new String[sites.size()];
    sites.toArray(arr);

 

posted @ 2023-03-20 22:54  曹伟666  阅读(36)  评论(0编辑  收藏  举报