首页 > 技术文章 > java实现,等待多个异步任务完成

wxdmw 2021-06-11 18:06 原文

今天和各位有缘看客分享两个东西,CountDownLatch和CompletableFuture。

之前在工作中遇到了一个场景,大意如下:

  主线程发起几个异步任务,然后等待所有异步任务完成后,才能进行下一步,那一次很栽面,居然没写出来,一方面知识匮乏、经验不足,一方面第一次遇到这种情况,心态有点慌。

最终请教了同组的大佬,大佬惊呼:CompletableFuture你不会吗?

有遇到类似场景的小伙伴,可以查一下这两个东西,首推CompletableFuture,这个东西很强大,但是,如果你像我当时一样,慌得一批,你可以先学一下CountDownLatch,使用简单,也能达到等待全部异步任务的效果。

简单写了个简易的小东西,初学的小伙伴可以参考下:

public class ParallelHandler<T> {

    private List<CompletableFuture<T>> futures;

    ParallelHandler () {
        this(10);
    }

    ParallelHandler (int size) {
        futures = new ArrayList<>(size);
    }

    public ParallelHandler addResTask (Supplier<T> supplier) {
        futures.add(CompletableFuture.supplyAsync(supplier));
        return this;
    }

    public List<CompletableFuture<T>> OK () {
        waits();
        return futures;
    }

    public void waits () {
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[]{})).join();
    }

    public void clear () {
        futures.clear();
    }
}

用法如下:

public static void main(String[] args) throws InterruptedException {
        ParallelHandler handler = new ParallelHandler();

        handler.addResTask(()->"done")
                .addResTask(()->{
                    try {
                        TimeUnit.SECONDS.sleep(2);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return "finally";
                });

        List<CompletableFuture<String>> futures = handler.OK();

        futures.stream().forEach(item -> {
            System.out.println(item.getNow("no result"));
        });
    }

就这么个意思吧,可以选择要返回值,也可以不要返回值,也可以clear然后复用。

根据实际情况,建议在使用中主动给CompletableFuture一个线程池。

推荐阅读