Wrayの知识库 Wrayの知识库
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • MacOS
  • Linux
  • Windows
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • MacOS
  • Linux
  • Windows
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
  • Java基础

    • Java概述
    • Java语法
    • 面向对象编程
    • Java数组
    • String字符串
    • 异常处理
  • Java集合

    • Java集合概述
    • ArrayList
    • LinkedList
    • HashMap
    • LinkedHashMap
    • HashSet
    • TreeMap
    • Queue&Deque
  • Java并发

    • Java并发概述
    • 线程与进程
    • Thread类与线程生命周期
    • 线程安全
    • synchronized关键字
    • volatile关键字
    • Java内存模型(JMM)
    • 线程间通信
    • 线程池
    • 并发工具类
    • 原子操作类Atomic
    • 并发锁
    • 并发容器
    • ConcurrentHashMap
    • BlockingQueue
    • CopyOnWriteArrayList
    • ThreadLocal
    • Fork/Join框架
    • ScheduledThreadPoolExecutor
    • CompletableFuture
      • 1. CompletableFuture 的基本概念
      • 2. CompletableFuture 的常用方法
      • 3. CompletableFuture 的执行机制
      • 4. CompletableFuture 的内部实现与源码分析
        • 4.1 thenApply 方法源码分析
      • 5. CompletableFuture 的应用场景
      • 6. CompletableFuture 的优缺点
      • 7. 总结
  • Java IO

    • Java IO概述
  • JVM

    • JVM概述
  • Java
  • Java并发
Wray
2024-11-01
目录

CompletableFuture

CompletableFuture 是 Java 8 引入的一个强大工具类,用于处理异步编程,它提供了流式的 API 和丰富的功能来构建复杂的异步任务。CompletableFuture 实现了 Future 接口,并增加了许多方法来简化异步计算的组合和处理。

# 1. CompletableFuture 的基本概念

  • 异步编程:CompletableFuture 提供了多种方式来执行异步任务,包括串行执行、并行执行、完成通知等。
  • 非阻塞:相对于传统的 Future,CompletableFuture 提供了一种非阻塞的机制来获取异步计算结果,通过回调机制执行后续操作,无需线程一直等待结果。
  • 函数式风格:CompletableFuture 结合了函数式编程的特性,通过 thenApply、thenAccept、thenCombine 等方法,以流式 API 方式编写异步逻辑,使代码更加简洁易读。

# 2. CompletableFuture 的常用方法

  • supplyAsync(Supplier<U> supplier):使用默认的线程池 ForkJoinPool 执行异步任务并返回一个 CompletableFuture,也可以通过指定自定义线程池来执行任务。
  • thenApply(Function<? super T,? extends U> fn):当 CompletableFuture 完成后,对结果进行处理,并返回新的 CompletableFuture。
  • thenAccept(Consumer<? super T> action):当 CompletableFuture 完成后,消费计算的结果,无返回值。
  • thenCombine(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn):两个 CompletableFuture 完成后,对它们的结果进行合并。
  • exceptionally(Function<Throwable, ? extends T> fn):处理 CompletableFuture 任务中的异常情况。

示例代码:

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CompletableFutureExample {
    public static void main(String[] args) {
        ExecutorService customExecutor = Executors.newFixedThreadPool(3);

        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + " is executing task...");
            return 42;
        }, customExecutor).thenApply(result -> {
            System.out.println("Applying function to result: " + result);
            return result * 2;
        }).exceptionally(ex -> {
            System.err.println("Exception occurred: " + ex.getMessage());
            return -1;
        });

        future.thenAccept(result -> System.out.println("Final result: " + result));
    }
}

在这个例子中,CompletableFuture 被用于异步地计算一个任务,并对其结果进行进一步处理。此示例中使用了自定义线程池 customExecutor 来执行异步任务。

# 3. CompletableFuture 的执行机制

  • 默认线程池:CompletableFuture 的异步任务默认使用 ForkJoinPool.commonPool(),也可以使用自定义的线程池来执行任务。
  • 任务依赖链:CompletableFuture 允许任务形成依赖链,通过 thenApply、thenCompose 等方法将多个任务串联起来执行,这种依赖链会保证任务的顺序执行。
  • 组合多个任务:通过方法如 thenCombine、allOf、anyOf,CompletableFuture 可以将多个异步任务组合在一起,实现复杂的任务协作。

# 4. CompletableFuture 的内部实现与源码分析

  • CompletableFuture 的数据结构:
    • CompletableFuture 内部通过一个 volatile 修饰的 Object result 来保存任务的结果或异常。
    • Stack:当一个 CompletableFuture 需要执行多个回调任务时,这些回调被存储在一个栈中,确保按顺序执行。
  • 异步任务的提交:当调用 supplyAsync() 或 runAsync() 时,任务会被提交到一个线程池中,默认是 ForkJoinPool,也可以指定自定义的线程池。
  • 任务的完成与回调:当一个 CompletableFuture 完成时,会调用 complete() 方法,通知所有注册的回调任务执行。源码中的 signallers() 方法用于遍历并唤醒等待的任务,确保它们能够及时执行。

# 4.1 thenApply 方法源码分析

  • thenApply() 方法:thenApply() 是用于在上一个任务完成后,对结果进行进一步处理并返回新的 CompletableFuture。
    public <U> CompletableFuture<U> thenApply(Function<? super T, ? extends U> fn) {
        return uniApplyStage(null, fn);
    }
    
    private <U> CompletableFuture<U> uniApplyStage(Executor e, Function<? super T, ? extends U> fn) {
        if (fn == null) throw new NullPointerException();
        CompletableFuture<U> d = new CompletableFuture<>();
        if (e != null || !d.uniApply(this, fn, null)) {
            UniApply<T,U> c = new UniApply<>(e, d, this, fn);
            push(c);
            c.tryFire(SYNC);
        }
        return d;
    }
    
    • uniApplyStage():用于创建一个新的 CompletableFuture,并注册一个回调函数来处理上一个任务的结果。
    • push():将回调任务压入栈中,以确保任务的有序执行。

# 5. CompletableFuture 的应用场景

  • 异步请求处理:在 Web 服务中,可以使用 CompletableFuture 进行异步请求处理,提升系统的吞吐量和响应速度。
  • 复杂任务的并行执行:CompletableFuture 通过 thenCombine、allOf 等方法,将多个独立的任务并行执行并合并结果,例如同时请求多个 API 并在全部完成后处理结果。
  • 任务重试与异常处理:exceptionally 和 handle 方法可以帮助开发者处理异步任务中的异常情况,实现任务重试机制。

# 6. CompletableFuture 的优缺点

  • 优点:
    • 简化异步编程:通过流式 API,简化了异步任务的管理,代码更加简洁和易读。
    • 丰富的组合功能:提供了多种方法来组合和管理异步任务,如 thenCombine、allOf 等。
    • 非阻塞:通过回调机制实现非阻塞的异步编程,提高了程序的性能。
  • 缺点:
    • 调试困难:由于异步任务的执行顺序不确定,调试和定位问题可能比较困难。
    • 线程池选择:默认的 ForkJoinPool 在某些场景中可能不合适,尤其是在 CPU 密集型任务中,容易导致线程竞争和性能下降。

# 7. 总结

CompletableFuture 是 Java 并发编程中的重要工具,通过丰富的 API 提供了灵活的异步任务管理方式。与传统的 Future 不同,CompletableFuture 结合了函数式编程的优点,使得开发者可以通过流式的方式来构建和管理异步任务。理解 CompletableFuture 的原理和应用场景,可以帮助开发者在多线程环境中编写更加高效、健壮的异步代码。

上次更新: 2024/11/01, 13:45:14
ScheduledThreadPoolExecutor
Java IO概述

← ScheduledThreadPoolExecutor Java IO概述→

Copyright © 2023-2024 Wray | 鄂ICP备2024050235号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式