CompletableFuture(异步编程)

CompletableFuture的由来

CompletableFuture实现了CompletionStage接口和Future接口,前者是对后者的一个扩展,增加了异步回调、流式处理、多个Future组合处理的能力,使Java在处理多任务的协同工作时更加顺畅便利。

代码示例(一)

thenCombine(合并)

public class Futrue {

    public static void main(String[] args) {
        System.out.println("小范来到了餐厅");
        System.out.println("小范点了 番茄炒蛋+ 一碗米饭");

        CompletableFuture<String> data = CompletableFuture.supplyAsync(() -> {
            System.out.println("厨师开始炒菜");
            work(5);
            return "番茄炒蛋";
        }).thenCombine(CompletableFuture.supplyAsync(() -> {
            System.out.println("服务员开始蒸米饭");
            work(2);
            return "米饭";
        }), (food1, food2) -> {
            return food1 + food1;
        });
        System.out.println("小范先打一把游戏等饭做好");
        System.out.println(data.join()+"饭做好了。小范开始吃饭");
        System.out.println("我吃完饭了");
    }


    //开始工作 workTime:工作时间
    public static void work(Integer workTime) {
        try {
            TimeUnit.SECONDS.sleep(workTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

小范来到了餐厅
小范点了 番茄炒蛋+ 一碗米饭
厨师开始炒菜
服务员开始蒸米饭
小范先打一把游戏等饭做好
服务员蒸完米饭
厨师炒完菜了
番茄炒蛋番茄炒蛋饭做好了。小范开始吃饭
我吃完饭了

这里我们发现厨师炒菜和服务员蒸米饭是同时进行的,最后并把两个线程的结果合并并返回

代码示例(二)

thenCompose(连接)

public class Futrue {

    public static void main(String[] args) {
        System.out.println("小范来到了餐厅");
        System.out.println("小范点了 番茄炒蛋+ 一碗米饭");

        CompletableFuture<String> data = CompletableFuture.supplyAsync(() -> {
            System.out.println("厨师开始炒菜");
            work(5);
            System.out.println("厨师炒菜完成");
            return "番茄炒蛋";


        }).thenCompose(dish -> CompletableFuture.supplyAsync(() -> {
            System.out.println("服务员开始打菜");
            work(2);
            System.out.println("服务员打菜完成");
            return dish + "米饭";
        }));

        System.out.println("小范先打一把游戏等饭做好");
        System.out.println(data.join()+"饭做好了。小范开始吃饭");
        System.out.println("我吃完饭了");
    }


    //开始工作 workTime:工作时间
    public static void work(Integer workTime) {
        try {
            TimeUnit.SECONDS.sleep(workTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

小范来到了餐厅
小范点了 番茄炒蛋+ 一碗米饭
厨师开始炒菜
小范先打一把游戏等饭做好
厨师炒菜完成
服务员开始打菜
服务员打菜完成
番茄炒蛋米饭饭做好了。小范开始吃饭
我吃完饭了

这里我们会发先厨师炒菜和服务员蒸米饭是顺序执行的,最后由服务员把菜和饭端给客人

代码示例(三)

thenApply 和thenCompose很相像

public class Futrue {

    public static void main(String[] args) {
        System.out.println("小范吃完饭了");
        System.out.println("小范结账,要求开发票");

        //场景:要求收款的和发票的是同一个人
        CompletableFuture<String> data = CompletableFuture.supplyAsync(() -> {
            System.out.println("服务员" + Thread.currentThread().getName() + "收款500");
            work(5);
            System.out.println("服务员" + Thread.currentThread().getName() + "收完款");
            return "500";
        }).thenApply(money -> {
            System.out.println("开票员" + Thread.currentThread().getName() + "开了"+money+"大小的发票");
            work(5);
            System.out.println("开票员" + Thread.currentThread().getName() + "开完了票");
            return "500元发票";
        });
        System.out.println("小范接了电话准备回家玩游戏");
        System.out.println(data.join() + "开好了。");
        System.out.println("小范回家");
    }


    //开始工作 workTime:工作时间
    public static void work(Integer workTime) {
        try {
            TimeUnit.SECONDS.sleep(workTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

小范吃完饭了
小范结账,要求开发票
服务员ForkJoinPool.commonPool-worker-9收款500
小范接了电话准备回家玩游戏
服务员ForkJoinPool.commonPool-worker-9收完款
开票员ForkJoinPool.commonPool-worker-9开了500大小的发票
开票员ForkJoinPool.commonPool-worker-9开完了票
500元发票开好了。
小范准备回家

代码示例(四)

applyToEither :获取执行速度最快的异步方法并返回结果

public class Futrue {

    public static void main(String[] args) {
        System.out.println("小范走出食堂,来到公交站");
        System.out.println("等待1路汽车 或者 2路汽车");
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println("1路汽车正在赶来");
            work(5);
            return "1路汽车";
        }).applyToEither(CompletableFuture.supplyAsync(() -> {
            System.out.println("2路汽车正在赶来");
            work(10);
            return "2路汽车";
        }), fisrtMethod -> fisrtMethod);

        System.out.println(completableFuture.join()+"汽车先来,坐上回家");
    }


    //开始工作 workTime:工作时间
    public static void work(Integer workTime) {
        try {
            TimeUnit.SECONDS.sleep(workTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

小范走出食堂,来到公交站
等待1路汽车 或者 2路汽车
1路汽车正在赶来
2路汽车正在赶来
1路汽车汽车先来,坐上回家

示例代码(五)

exceptionally:异步编程异常处理

public class Futrue {

    public static void main(String[] args) {
        System.out.println("小范走出食堂,来到公交站");
        System.out.println("等待1路汽车 或者 2路汽车");
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println("1路汽车正在赶来");
            work(5);
            return "1路汽车";
        }).applyToEither(CompletableFuture.supplyAsync(() -> {
            System.out.println("2路汽车正在赶来");
            work(10);
            return "2路汽车";
        }), fisrtMethod -> {
            if (fisrtMethod.equals("1路汽车")) {
                throw new RuntimeException("撞树了");
            }
            return fisrtMethod;
        }).exceptionally(e -> {
            System.out.println(e.getMessage());
            System.out.println("小白叫了出租车回家");
            return "出租车";
        });

        System.out.println(completableFuture.join() + "汽车先来,坐上回家");
    }


    //开始工作 workTime:工作时间
    public static void work(Integer workTime) {
        try {
            TimeUnit.SECONDS.sleep(workTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

小范走出食堂,来到公交站
等待1路汽车 或者 2路汽车
1路汽车正在赶来
2路汽车正在赶来
java.lang.RuntimeException: 撞树了
小白叫了出租车回家
出租车汽车先来,坐上回家

posted @ 2022-04-12 17:30  xiye1  阅读(19)  评论(0)    收藏  举报