CompletableFuture的使用

Java 8 中, 新增加了一个包含 50 个方法左右的类–CompletableFuture,它提供了非常强大的 Future 的扩展功能,可以帮助我们简化异步编程的复杂性,并且提供了函数式编程的能力,可以通过回调的方式处理计算结果,也提供了转换和组合 CompletableFuture 的方法。

优点
我们可以不用再去手工维护线程,任务分配的工作我们不再关注。
语义清晰,只用专注业务逻辑。

// two任务有返回值, one任务没有返回值
// 聚合and ,只有one和two都执行完毕才会执行three任务
			CompletableFuture<Void> one = CompletableFuture.runAsync(() -> {
	                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("任务1");
            });
            CompletableFuture<String> two = CompletableFuture.supplyAsync(() -> {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("任务2");
                return "world";
            });

            CompletableFuture<String> three = one.thenCombine(two, (s, tf) -> {
                System.out.println(s);
                System.out.println("任务3" + tf);
                return tf + "123";
            });
            System.out.println(three.join());

创建在这里插入图片描述
runAsync方法不支持返回值,supplyAsync支持返回值,他们也都执行自己指定的线程池。如果不指定的话, 它们都是用的一个线程池ForkJoinPool。默认线程数为CPU的核数。我们一定要根据不同业务类型创建不同线程池。

创建完成CompletableFuture对象后,会自动异步的执行runnable.run方法或者supplier.get方法。对于一个异步操作,我们只需要关心1.异步什么时候结束,2.如何获取异步执行的结果。

CompletionStage提供了40多种方法,用于表示任务与任务之间的关系。
在这里插入图片描述
1.串行关系,主要是thenApply、thenAccept、thenRun和thenCompose这四 个系列的接口。

//支持返回值和入参
 public <U> CompletableFuture<U> thenApply(
        Function<? super T,? extends U> fn) {
        return uniApplyStage(null, fn);
    }
    //支持入参
  public CompletableFuture<Void> thenAccept(Consumer<? super T> action) {
        return uniAcceptStage(null, action);
    }
    //不接受入参,也不接受返回值
public CompletableFuture<Void> thenRun(Runnable action) {
        return uniRunStage(null, action);
    }


CompletableFuture<String> f0 =
    CompletableFuture.supplyAsync(
() -> "Hello World") //1 .thenApply(s -> s + " QQ") //2 .thenApply(String::toUpperCase);//3
System.out.println(f0.join()); //输出结果
HELLO WORLD QQ
  1. 描述AND汇聚关系
    CompletionStage接口里面描述AND汇聚关系,主要是thenCombine、thenAcceptBoth和runAfterBoth系列的接口.
  public <U,V> CompletableFuture<V> thenCombine(
        CompletionStage<? extends U> other,
        BiFunction<? super T,? super U,? extends V> fn) {
        return biApplyStage(null, other, fn);
    }
    
public <U> CompletableFuture<Void> thenAcceptBoth(
        CompletionStage<? extends U> other,
        BiConsumer<? super T, ? super U> action) {
        return biAcceptStage(null, other, action);
    }
    
 public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other,
                                                Runnable action) {
        return biRunStage(null, other, action);
    }

3.OR汇聚关系

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

public CompletableFuture<Void> acceptEither(
        CompletionStage<? extends T> other, Consumer<? super T> action) {
        return orAcceptStage(null, other, action);
    }
    
 public CompletableFuture<Void> runAfterEither(CompletionStage<?> other,
                                                  Runnable action) {
        return orRunStage(null, other, action);
    }

4.异常处理
上面的方法都不允许抛出可检查异常,但我们无法限制它抛出运行时异常,因此提供了方法。

//catch
public CompletableFuture<T> exceptionally(
        Function<Throwable, ? extends T> fn) {
        return uniExceptionallyStage(fn);
    }
//finally
 public CompletableFuture<T> whenComplete(
        BiConsumer<? super T, ? super Throwable> action) {
        return uniWhenCompleteStage(null, action);
    }
//finally
 public <U> CompletableFuture<U> handle(
        BiFunction<? super T, Throwable, ? extends U> fn) {
        return uniHandleStage(null, fn);
    }

exceptionally()的使用非常类似于 try{}catch{}中的catch{},但是由于支持链式编程方式,所以相对更简单。既然有try{}catch{},那就一定还 有try{}finally{},whenComplete()和handle()系列方法就类似于try{}finally{}中的finally{},无论是否发生异 常都会执行whenComplete()中的回调函数consumer和handle()中的回调函数fn。whenComplete()和 handle()的区别在于whenComplete()不支持返回结果,而handle()是支持返回结果的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值