异步编程之美——CompletableFuture

supplyAsync

异步开启一个任务,并返回一个结果;入参为Supply函数式接口;

CompletableFuture busA = CompletableFuture.supplyAsync(() -> {
    SmallTool.printTimeAndThread("A公车发车");
    SmallTool.sleepMillis(3000);
    return "A公车到站";
});
SmallTool.printTimeAndThread(busA);

thenCombine

连接两个异步任务,即接收两个异步任务的结果,入参为CompletableStage和BiFunction函数式接口;
也可以等价于在调用了两个CompletableFuture的join()方法后将结果输入到BiFunction;

SmallTool.printTimeAndThread("小白下单烧鸭饭");
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
    SmallTool.printTimeAndThread("大厨斩烧鸭!");
    SmallTool.sleepMillis(3000);
    return "烧鸭ok";
}).thenCombine(CompletableFuture.supplyAsync(() -> {
    SmallTool.printTimeAndThread("服务员煮米饭");
    SmallTool.sleepMillis(2000);
    return "米饭ok";
}), (d, r) -> {
    SmallTool.printTimeAndThread(d);
    SmallTool.printTimeAndThread(r);
    return "服务员盛饭";
});
SmallTool.printTimeAndThread("小白打游戏");
SmallTool.printTimeAndThread(completableFuture.join());
SmallTool.printTimeAndThread("小白吃烧鸭饭");

执行结果

thenCompose

用于串联两个异步任务,即在前一个任务结束后将其结果作为入参传入Function,Function内部再启动一个CompletableFuture并执行;输入形参是
Function<? super T, ? extends CompletionStage>;

SmallTool.printTimeAndThread("小白到餐厅点餐,点了米饭 + 烧鸭! ");
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
    SmallTool.printTimeAndThread("大厨砍烧鸭 ");
    SmallTool.sleepMillis(3000);
    return "大厨砍完鸭";
}).thenCompose((res) -> CompletableFuture.supplyAsync(() -> {
    SmallTool.printTimeAndThread(res);
    SmallTool.printTimeAndThread("服务员盛饭!");
    SmallTool.sleepMillis(1000);
    return "上菜";
}));
SmallTool.printTimeAndThread("小白打游戏");
SmallTool.printTimeAndThread(String.format("%s, 小白吃饭", completableFuture.join()));

执行结果

applyToEither

用于处理当两个线程都在执行时,不管哪个先执行完,只要有一个返回就触发另一个CompletableStage的执行

CompletableFuture.supplyAsync(() -> {
    SmallTool.printTimeAndThread("A公车发车");
    SmallTool.sleepMillis(3000);
    return "A公车到站";
}).applyToEither(CompletableFuture.supplyAsync(() -> {
            SmallTool.printTimeAndThread("B公车发车");
            SmallTool.sleepMillis(2000);
            return "B公车到站";
        }), bus -> bus
).thenCompose(bus -> CompletableFuture.runAsync(() -> {
    SmallTool.printTimeAndThread(String.format("%s , 小白上车", bus));
})).join();

运行结果

thenApply

用于将上次的结果作为当前本次操作的输入参数,该方法接收形参是Function<U,V>;有别于thenCompose的Function<U, V extends CompletableStage>;

CompletableFuture.supplyAsync(() -> {
    SmallTool.printTimeAndThread("项目经历开始讲解需求");
    SmallTool.sleepMillis(2000);
    return "讲解完毕";
}).thenApply((preRes) -> {
    SmallTool.printTimeAndThread(String.format("项目经理 %s, 程序员开始编码", preRes));
    SmallTool.sleepMillis(3000);
    return "编码完毕";
}).thenCompose((preRes) -> CompletableFuture.runAsync(() ->{
    SmallTool.printTimeAndThread(preRes);
    SmallTool.printTimeAndThread("打包构建");
    SmallTool.sleepMillis(2000);
    SmallTool.printTimeAndThread("上测试环境");
})).thenRun(() -> {
    SmallTool.printTimeAndThread("测试小哥开始测试");
    SmallTool.sleepMillis(1000);
    SmallTool.printTimeAndThread("无发现bug");
    SmallTool.printTimeAndThread("上线");
}).join();

运行结果

exceptionally

用于获取异步任务的异常结果并进行处理;
入参是Function<Throwable, ? extends T>函数式接口;

CompletableFuture.runAsync(() -> {
    SmallTool.printTimeAndThread("出bug 出bug 出bug");
    SmallTool.sleepMillis(3000);
    throw new RuntimeException("bug");
}).exceptionally((e) -> {
    e.printStackTrace();
    return null;
}).join();

运行结果

handle

不管是正常还是异常结束,当执行完毕时会调用该方法;
入参是BiFunction<? super T, Throwable, ? extends U>,返回一个CompletableFuture;

CompletableFuture<String> join = CompletableFuture.supplyAsync(() -> {
    SmallTool.sleepMillis(1000);
    return "avc";
}).handle((res, e) -> {
    return CompletableFuture.supplyAsync(() -> {
        SmallTool.printTimeAndThread(res);
        e.printStackTrace();
        return "bvc";
    });
}).join();
System.out.println(join);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值