CompletableFuture.thenAccept方法的两种情况

使用CompletableFuture

感觉这玩意和JSPromise很像。先来回顾下如何使用:

CompletableFuture.supplyAsync(()->{
    return 1;
}).thenAccept((result)->{
    System.out.println(result);
}).exceptionally((e)->{
    System.out.println(e);
    return null;
});

首先CompletableFuture这个类来自于java.util.concurrent包。我们想要使用直接调用其静态方法supplyAsync(Supplier<U> supplier)就行。

supplyAsync会通过ForkJoinPool.commonPool()线程池启动一个工作线程来执行我们传入的supplier,然后将结果返回。

接下来就可以使用thenAccept(Consumer<? super T> action)来处理supplyAsync方法正常执行完毕返回的结果。

然后还会使用exceptionally(Function<Throwable, ? extends T> fn)来处理supplyAsync方法执行时出现的异常。

thenAcceptexceptionally之间只可能执行其中一个。

需要注意的是,CompletableFuture所执行的任务都被设定为守护线程,这意味着主线程执行完毕时,它即使没有执行完毕,程序也会关闭。

下面开始说重点:

CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName());
            return 1 / 1;
}).thenAccept((r) -> {
            System.out.println(Thread.currentThread().getName());
            System.out.println(Thread.currentThread().isDaemon());
});
Thread.sleep(100);

注意:大概有两种情况:

  • supplyAsync还未完成,而thenAccept欲获取supplyAsync返回值时,thenAccept则会将此后续任务放入栈中,由supplyAsync将前置任务执行完毕后继续执行后续任务。此时前置任务与后续任务的执行都是在同一个工作线程中执行。
ForkJoinPool.commonPool-worker-1
true
ForkJoinPool.commonPool-worker-1
true
  • supplyAsync已完成,thenAccept则获取supplyAsync返回值,将后续任务在当前线程执行完毕,因此前置任务在工作线程中执行,而后续任务在当前线程中执行。
ForkJoinPool.commonPool-worker-1
true
main
false

相较于thenAccept执行线程的不确定性,thenAcceptAsync执行的后续任务则总是与前置任务在同一个线程执行,也就是前置任务与后置任务都在一个工作线程中执行。

CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName());
            return 1 / 1;
}).thenAcceptAsync((r) -> {
            System.out.println(Thread.currentThread().getName());
            System.out.println(Thread.currentThread().isDaemon());
});
Thread.sleep(100);
/*
ForkJoinPool.commonPool-worker-1
true
ForkJoinPool.commonPool-worker-1
true
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值