Java8新特性之CompletableFuture

Java8新特性之CompletableFuture

CompletableFuture java8推出,java9增强,功能非常强大,可以编排异步任务,完成串行执行,并行执行,AND 汇聚关系,OR 汇聚关系。

任务之间的关系 并发、依赖、互斥

先弄个工具类,用来后面进行打印调试。

public class TestTool {
    public static void sleepMillis(long millis) {
        try {
            Thread.sleep(millis); // 模拟线程操作时间
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }

    public static void printTimeAndThread(String tag){
        String result = 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(result);
    }
}

1、 runAsync 和 supplyAsync方法

没有指定Executor的方法会使用ForkJoinPool.commonPool() 作为它的线程池执行异步代码。如果指定线程池,则使用指定的线程池运行。以下所有的方法都类同。

下面例子completableFuture.join() 会等待 返回supplyAsync方法执行结束的结果 “菜品上齐”

public class completableFutureTest {
    public static void main(String[] args){
        TestTool.printTimeAndThread("小华进入餐厅");
        TestTool.printTimeAndThread("小华点了 半只姜母鸭 + 一瓶可乐");
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
            TestTool.printTimeAndThread("小福贵制作姜母鸭");
            TestTool.sleepMillis(200);
            TestTool.printTimeAndThread("小福贵拿可乐");
            TestTool.sleepMillis(100);
            return "菜品上齐";
        });
        TestTool.printTimeAndThread("小华在刷微博");
        TestTool.printTimeAndThread(String.format("%s,小华开吃", completableFuture.join()));
        TestTool.printTimeAndThread("小华吃完");
    }
}

2、thenCompose 前一个任务完成,有结果后,下一个任务才会触发

用来连接两个异步任务

入参dish 是"姜母鸭出锅" 而 出参需要一个CompletionStage的实现

public class completableFutureTest {
    public static void main(String[] args){
        TestTool.printTimeAndThread("小华进入餐厅");
        TestTool.printTimeAndThread("小华点了 半只姜母鸭 + 一碗米饭");
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
            TestTool.printTimeAndThread("小福贵制作姜母鸭");
            TestTool.sleepMillis(200);
            return "姜母鸭出锅";
        }).thenCompose(dish -> CompletableFuture.supplyAsync(() ->{
            TestTool.printTimeAndThread("服务员拿米饭");
            TestTool.sleepMillis(100);
            return dish + ",米饭送到";
        }));
        TestTool.printTimeAndThread("小华在刷微博");
        TestTool.printTimeAndThread(String.format("%s,小华开吃", completableFuture.join()));
        TestTool.printTimeAndThread("小华吃完");
    }
}

3、thenCombine 合并任务

thenCombine 会把 两个 CompletionStage 的任务都执行完成后,把两个任务的结果一块交给 thenCombine 来处理。

thenCombine 需要两个参数,一个CompletionStage的实现,一个BiFunction

BiFunction的作用是把两个值,转成一个值,可自己查看源码。

public class completableFutureTest {
    public static void main(String[] args){
        TestTool.printTimeAndThread("小华进入餐厅");
        TestTool.printTimeAndThread("小华点了 半只姜母鸭 + 一碗米饭");
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
            TestTool.printTimeAndThread("小福贵制作姜母鸭");
            TestTool.sleepMillis(200);
            return "姜母鸭";
        }).thenCombine(CompletableFuture.supplyAsync(() ->{
            TestTool.printTimeAndThread("服务员蒸饭");
            TestTool.sleepMillis(100);
            return "米饭";
        }),(dish, rice) ->{
            TestTool.printTimeAndThread("服务员打饭");
            TestTool.sleepMillis(100);
            return String.format("%s + %s 好了", dish, rice);
        });
        TestTool.printTimeAndThread("小华在刷微博");
        TestTool.printTimeAndThread(String.format("%s,小华开吃", completableFuture.join()));
        TestTool.printTimeAndThread("小华吃完");
    }
}

4、thenApply、thenApplyAsync

用来做任务的后置处理,有些场景可用thenCompose替代。

5、applyToEither

用来获取最先完成的任务。

public <U> CompletableFuture<U> applyToEither(
        CompletionStage<? extends T> other, Function<? super T, U> fn) {
        return orApplyStage(null, other, fn);
    }

上个任务和这个任务一起运行,哪个先运行完成,就把哪个任务结果交给Function

public class completableFutureTest {
    public static void main(String[] args) {
        TestTool.printTimeAndThread("小华到公交站");
        TestTool.printTimeAndThread("等待 8路 或者 11路 公交车");
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
            TestTool.printTimeAndThread("8路公交车正在驶来");
            TestTool.sleepMillis(1000);
            return "8路到了";
        }).applyToEither(CompletableFuture.supplyAsync(() -> {
            TestTool.printTimeAndThread("11路公交车正在驶来");
            TestTool.sleepMillis(200);
            return "11路到了";
        }), firstComeBus -> firstComeBus);
        TestTool.printTimeAndThread(String.format("%s,小华上车", completableFuture.join()));
    }
}

6、exceptionally

用来处理异常。

public CompletableFuture<T> exceptionally(
        Function<Throwable, ? extends T> fn) {
        return uniExceptionallyStage(fn);
    }

遇到异常时的处理动作

public class completableFutureTest {
    public static void main(String[] args) {
        TestTool.printTimeAndThread("小华到公交站");
        TestTool.printTimeAndThread("等待 8路 或者 11路 公交车");
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
            TestTool.printTimeAndThread("8路公交车正在驶来");
            TestTool.sleepMillis(1000);
            return "8路到了";
        }).applyToEither(CompletableFuture.supplyAsync(() -> {
            TestTool.printTimeAndThread("11路公交车正在驶来");
            TestTool.sleepMillis(200);
            return "11路到了";
        }), firstComeBus -> {
            TestTool.printTimeAndThread(firstComeBus);
            if (firstComeBus.startsWith("11")){
                throw new RuntimeException("追尾了");
            }
            return firstComeBus;
        }).exceptionally(e ->{
            TestTool.printTimeAndThread(e.getMessage());
            TestTool.printTimeAndThread("小华直接叫滴滴");
            return "滴滴到了";
        }); 
        TestTool.printTimeAndThread(String.format("%s,小华上车", completableFuture.join()));
    }
}

7、allOf

归并结果

CompletableFuture<String> completableFuture1;
CompletableFuture<String> completableFuture2;
CompletableFuture<String> completableFuture3;
CompletableFuture.allOf(completableFuture1,completableFuture2,completableFuture3).join();
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值