CompletableFuture高并发和线程池使用

文章目录

概要

多线程+CountDownLatch

线程池+CompletableFuture

CompletableFuture介绍


概要

在Java中,有些任务单线程执行时间长,一般会使用多线程增加并发提高运行速率。但很多情况下,需要所有子线程执行完,才能往下执行主线程,一般我们会使用这些方案:

1、多线程+CountDownLatch

2、线程池+CompletableFuture

多线程+CountDownLatch

public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(10);
 
        for (int i=0; i<4; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + " 运行");
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        latch.countDown();
                    }
                }
            }).start();
        }
 
        System.out.println("等待子线程运行结束");
        latch.await(10, TimeUnit.SECONDS);
        System.out.println("子线程运行结束");
}
 

缺点:经常会忘记写latch.countDown();,或者latch.countDown()未执行,导致线程阻塞

线程池+CompletableFuture

1、多个子线程全部执行完,才能继续往下,阻塞主线程

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(8, 10,
        10, TimeUnit.SECONDS,
        new LinkedBlockingQueue<>(Integer.MAX_VALUE));

CompletableFuture task3 = CompletableFuture.runAsync(() -> {
    //TODO do something
}, threadPoolExecutor);

CompletableFuture task5 = CompletableFuture.runAsync(() -> {
    //TODO do something
}, threadPoolExecutor);
CompletableFuture headerFuture = CompletableFuture.allOf(task3, task5);
headerFuture.join();

//继续主线程

2、多个子线程,每个单独异步执行,不阻塞主线程

CompletableFuture task3 = CompletableFuture.runAsync(() -> { //TODO do something }, threadPoolExecutor);

CompletableFuture task5 = CompletableFuture.runAsync(() -> { //TODO do something }, threadPoolExecutor);

3、exceptionally使用,处理异常

CompletableFuture.runAsync(() -> { //TODO do something }, threadPoolExecutor).exceptionally(e -> {
    if (e instanceof CompletionException || e instanceof ExecutionException) {
        if (e.getCause() != null) {
            e = e.getCause();
        }
    }
    return MxtyDdlCompletableDTO.builder().throwable(e).build();
});

4、多个子线程执行完成,统计处理结果

List> futureList = new ArrayList<>();
for (List list : partition) {
    CompletableFuture future = CompletableFuture.supplyAsync(() -> {
        tableCountNumSql(dqlDecorator, list, map);
        return MxtyDdlCompletableDTO.builder().build();
    }, ddlTaskPool).exceptionally(e -> {
        if (e instanceof CompletionException || e instanceof ExecutionException) {
            if (e.getCause() != null) {
                e = e.getCause();
            }
        }
        return MxtyDdlCompletableDTO.builder().throwable(e).build();
    });
    futureList.add(future);
}
for (CompletableFuture future : futureList) {
    MxtyDdlCompletableDTO dto = future.join();
    if (dto == null || dto.getThrowable() != null) {
     
    }
}

CompletableFuture介绍

CompletableFuture是Java中的一个类,表示异步计算的未来结果。它是java.util.concurrent包的一部分,作为Future接口的增强功能在Java 8中引入的。
CompletableFuture类的一些关键特性包括:
1. 异步执行:CompletableFuture允许您异步执行任务,这意味着调用线程可以在不等待任务完成的情况下继续执行。
2. 完成阶段:CompletableFuture引入了CompletionStage的概念,它表示可能最终完成并返回值或异常的计算阶段。CompletionStage提供了将多个阶段链接在一起并定义它们之间依赖关系的方法。
3. 回调和可组合性:CompletableFuture支持回调,在未来完成时执行。您可以使用 `thenApply()` 、 `thenAccept()` 和 `thenRun()` 等方法附加回调。此外,CompletableFuture还提供了 `thenCompose()` 和 `thenCombine()` 等方法,用于组合多个未来。
4. 异常处理:CompletableFuture允许您处理计算过程中发生的异常,使用 `exceptionally()` 和 `handle()` 等方法。这些方法提供了处理和恢复异常的灵活性。
5. 异步组合器:CompletableFuture提供了一组称为"组合器"的方法,允许您组合多个未来、等待它们全部完成或选择第一个完成的未来。
总的来说,CompletableFuture为Java中的异步计算提供了强大而灵活的方式,使您能够编写更高效和响应性的代码。

你可能感兴趣的:(java,#,高并发,java,多线程)