首页 Java 正文
  • 本文约2110字,阅读需11分钟
  • 68
  • 0

【多线程与并发】CompletableFuture用法

摘要

原理 CompletableFuture 是 Java 8 引入的一个新的并发编程工具,用于处理异步任务和异步编程。 它提供了一种简单、强大和灵活的方式来处理异步计算、响应式编程和任务组合。 CompletableFuture 相比于传统的 Future 接口,提供了更强大的功能和更好的编程体验。 CompletableFuture 的核心原理可以概括为以下...

原理

CompletableFuture 是 Java 8 引入的一个新的并发编程工具,用于处理异步任务和异步编程。

它提供了一种简单、强大和灵活的方式来处理异步计算、响应式编程和任务组合。

CompletableFuture 相比于传统的 Future 接口,提供了更强大的功能和更好的编程体验。

CompletableFuture 的核心原理可以概括为以下几点:

  1. 异步任务执行
    • CompletableFuture 可以从 Executor(默认使用 ForkJoinPool.commonPool())中获取线程执行任务,而不是使用主线程进行阻塞。这样可以充分利用多核处理器的性能,提高并行处理能力。
  2. 链式调用
    • CompletableFuture 提供了一系列的链式调用方法(如 thenApply(), thenCompose(), thenCombine() 等),使得任务之间的依赖关系更加清晰和简洁。开发者可以通过简单的流式调用来编排任务的执行顺序。
  3. 异常处理
    • CompletableFuture 提供了更灵活和丰富的异常处理机制。可以通过方法链中的 exceptionally() 或 handle() 方法来处理任务执行过程中的异常情况,实现统一的异常处理逻辑。
  4. 完成回调
    • CompletableFuture 可以注册任务完成的回调函数,当任务完成时自动触发回调。这样可以更方便地处理任务的结果,并进行后续操作。
  5. 组合任务
    • CompletableFuture 提供了 allOf() 和 anyOf() 等方法,可以组合多个 CompletableFuture 任务的结果。这样可以实现并行执行多个任务并等待它们的结果,或者等待任意一个任务完成。
  6. 状态管理
    • CompletableFuture 通过内部的 volatile 变量来管理任务的状态(未完成、完成、异常),并使用 CAS(Compare-And-Swap)操作保证线程安全。
  7. 任务调度机制
    • CompletableFuture 的任务调度机制基于 ForkJoinPool 的工作窃取算法。当一个线程完成当前任务后,会从其他线程的任务队列中窃取任务执行,从而提高 CPU 利用率。

示例与讲解

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CompletableFutureExample {

    public static void main(String[] args) {
        // 创建一个异步任务,模拟一个长时间运行的计算
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(2); // 模拟耗时操作
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new IllegalStateException(e);
            }
            return "Hello, World!";
        });

        // 处理任务结果
        future.thenApply(result -> result + " from CompletableFuture")
              .thenAccept(System.out::println);

        // 处理任务异常
        future.exceptionally(ex -> {
            System.out.println("An error occurred: " + ex.getMessage());
            return "Default result";
        });

        // 设置超时时间,并处理超时情况
        try {
            String result = future.get(1, TimeUnit.SECONDS); // 等待任务完成,最多等待1秒
            System.out.println("Result: " + result);
        } catch (TimeoutException e) {
            System.out.println("Task timed out.");
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
}

在这个示例中:

  1. 异步任务执行
    • 使用 CompletableFuture.supplyAsync() 方法提交了一个异步任务,该任务在后台线程中执行并返回结果。
  2. 链式调用
    • 通过 thenApply() 方法对任务结果进行转换,并通过 thenAccept() 方法消费结果。
  3. 异常处理
    • 使用 exceptionally() 方法处理任务执行过程中可能发生的异常。
  4. 超时处理
    • 使用 future.get(1, TimeUnit.SECONDS) 方法等待任务完成,最多等待1秒。如果任务在1秒内没有完成,将抛出 TimeoutException,并在 catch 块中进行处理。

扫描二维码,在手机上阅读


    评论