CompletableFuture中的thenRun和thenRunAsync方法

2 篇文章 0 订阅
1 篇文章 0 订阅

需求:

我需要在做完第一件事情后,再做第二件事情。

代码编程:

    @Resource(name = "globalThreadPool")
    private ThreadPoolExecutor threadPoolExecutor;
    
	CompletableFuture.runAsync(() -> {
	做第一件事情;
	},threadPoolExecutor).thenRun(()->{
   做第二件事情
   });

其中做第二件事情的时候CompletableFuture提供了三个方法,源码如下。
CompletableFuture源码:

public CompletableFuture<Void> thenRun(Runnable action) {
    return uniRunStage(null, action);
}


public CompletableFuture<Void> thenRunAsync(Runnable action) {
    return uniRunStage(asyncPool, action);
}


public CompletableFuture<Void> thenRunAsync(Runnable action,
                                            Executor executor) {
    return uniRunStage(screenExecutor(executor), action);
}

可以看到它们都内部调用了uniRunStage(Executor e, Runnable f) 方法:

    private CompletableFuture<Void> uniRunStage(Executor e, Runnable f) {
        if (f == null) throw new NullPointerException();
        CompletableFuture<Void> d = new CompletableFuture<Void>();
        if (e != null || !d.uniRun(this, f, null)) {
            UniRun<T> c = new UniRun<T>(e, d, this, f);
            push(c);
            c.tryFire(SYNC);
        }
        return d;
    }

分析

thenRun方法

可以看到它调用没有传入uniRunStage(Executor e, Runnable f) 方法时候Executor参数传的null,所以它是使用的是执行上一个任务的线程池。

  • 也就是说,如果你执行第一个任务的时候,传入了一个线程池,当执行第二个任务的时候调用的是thenRun方法,则第二个任务和第一个任务是公用同一个线程池。
thenRunAsync(Runnable action)方法

可以看到它调用没有传入uniRunStage(Executor e, Runnable f) 方法时候Executor参数传的asyncPool,所以它是使用的默认的ForkJoin线程池。
private static final Executor asyncPool = useCommonPool ? ForkJoinPool.commonPool() : new ThreadPerTaskExecutor();

  • 也就是说,如果你执行第一个任务的时候,传入了一个线程池,当执行第二个任务的时候调用的是thenRunAsync(Runnable action)方法,则第一个任务使用的是你传入的线程池,第二个任务使用的是ForkJoin线程池,由于ForkJoin线程池是整个应用程序公用的,比如stream使用方法parallel()进行并行运算的时候也是用的ForkJoin线程池,该线程池可以在程序启动的时候进行设置,详情请百度。由于是ForkJoin线程池是公用的,所以,不建议你在不知道程序其他地方哪里还会使用该线程池的情况下使用。
thenRunAsync(Runnable action,Executor executor)方法

可以看到它调用没有传入uniRunStage(Executor e, Runnable f) 方法时候Executor参数传的是外部传入的自定义线程池,所以它是使用的你指定的线程池。

  • 也就是说,如果你执行第一个任务的时候,传入了A线程池,当执行第二个任务的时候调用的是thenRunAsync(Runnable action,Executor executor)方法并传入了B线程池,则第一个任务使用的是A线程池,第二个任务使用的是B线程池。
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值