探索 Java 中的 CompletableFuture:简化异步编程

ops/2024/9/24 21:19:30/

CompletableFuture 简介

CompletableFuture 是 Java 并发 API 的一部分,代表了异步计算的结果,并且可以对其进行操作和组合。与 Future 接口相比,CompletableFuture 提供了更多的灵活性和控制能力,允许开发者以声明式的方式构建复杂的异步逻辑。
基本用法

创建 CompletableFuture

创建 CompletableFuture 实例有多种方式:

使用 supplyAsync 来异步执行一个供应者函数。
使用 runAsync 来异步执行一个 Runnable 任务。
使用 completedFuture 来立即完成一个 Future。
java">CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {// 模拟长时间运行的任务timeConsumingTask();return "Result";
});

处理结果

使用 thenApply、thenAccept 或 thenRun 来处理异步操作的结果:

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

异常处理

CompletableFuture 提供了 exceptionally 方法来处理可能发生的异常:

java

java">future.exceptionally(throwable -> {System.err.println("Error occurred: " + throwable.getMessage());return null;
});

组合 CompletableFuture

CompletableFuture 的强大之处在于它可以与其他 CompletableFuture 实例组合,创建更复杂的异步逻辑。
组合多个 CompletableFuture

使用 allOf 或 anyOf 来等待多个 CompletableFuture 实例完成:

java">CompletableFuture<Void> allDone = CompletableFuture.allOf(future1, future2, future3);

链式调用

使用 thenCompose 来创建一个基于前一个 CompletableFuture 结果的新 CompletableFuture:

java">future.thenCompose(result -> {return new CompletableFuture<>()...; // 根据结果创建新的任务
});

并行执行

使用 runAsync 并行执行多个任务,然后使用 thenAcceptBoth 等方法来处理它们的结果:

java">CompletableFuture<String> futureA = CompletableFuture.supplyAsync(() -> "A");
CompletableFuture<Integer> futureB = CompletableFuture.supplyAsync(() -> 1);futureA.thenAcceptBoth(futureB, (a, b) -> {System.out.println("Result from A: " + a + ", Result from B: " + b);
});

优势与最佳实践

非阻塞:CompletableFuture 提供了一种非阻塞的方式来处理异步操作。
易于组合:可以轻松地将多个异步操作组合成复杂的逻辑。
错误处理:提供了更好的错误处理机制。
API 丰富:提供了大量方法来处理各种异步场景。

最佳实践

使用 supplyAsync 来异步执行计算密集型任务。
使用 runAsync 来异步执行 I/O 密集型任务。
总是考虑异常处理,使用 exceptionally 来优雅地处理错误。
避免在 CompletableFuture 的链中同步阻塞,这会丧失异步的优势。

结论

CompletableFuture 是 Java 并发编程中一个非常有用的工具,它提供了一种简洁、强大的方式来编写异步、非阻塞的代码。通过本文的介绍,你应该能够理解 CompletableFuture 的基本概念,并开始在项目中使用它来简化多线程编程。记住,合理使用 CompletableFuture 可以显著提高应用程序的性能和响应能力。


http://www.ppmy.cn/ops/94684.html

相关文章

C语言典型例题36

《C程序设计教程&#xff08;第四版&#xff09;——谭浩强》 例题3.4 输入一个字符&#xff0c;判别它是否为大写字母&#xff0c;如果是&#xff0c;将它转换为小写字母&#xff1a;如果不是&#xff0c;不转换。然后输出最后要输出的字符。 代码&#xff1a; //《C程序设计…

STM32使用串口DMA发送+空闲中断

/* 使用串口DMA发送空闲中断 注意使能串口中断和DMA中断 考虑发送超时处理机制。 */ void init_Myuart(void){ HAL_UARTEx_ReceiveToIdle_DMA(&huart1,rx_buf, sizeof(rx_buf)); } void myuart_send(uint8_t * send_data,uint16_t lenght) { HAL_UART_Transmit_DMA(&…

a 方法调用 b 方法 2个方法都有事务,且传播特性相同或不同。举例所有排列组合场景,并详细说明

在Java中&#xff0c;事务的传播特性定义了方法调用中事务的行为。常见的传播特性包括&#xff1a; REQUIRED&#xff08;默认&#xff09;&#xff1a;如果当前存在事务&#xff0c;则加入该事务&#xff1b;如果没有事务&#xff0c;则创建一个新的事务。 REQUIRES_NEW&…

掌握系统思维:如何成为项目比赛中的制胜法宝

掌握系统思维&#xff1a;如何成为项目比赛中的制胜法宝 前言系统思维&#xff1a;项目管理的核心竞争力整体大于部分之和系统思维的实践应用涌现性&#xff1a;团队协作的奇迹系统科学的启示结语 前言 在这个快速变化的时代&#xff0c;项目管理不仅仅是关于任务的完成&#x…

在Ubuntu上有什么命令,或者是系统文件能告诉我链接nvme ssd的pcie槽位是不是支持热插拔功能?

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

【网络编程】TCP实现网络通信(C语言、Ubuntu实现)

TCP服务器通信模型&#xff1a;&#xff08;分为以下6个步骤&#xff09; 1、sfd socket(); //创建一个用于连接的套接字文件描述符 2、bind(); //为服务器套接字绑定ip地址和端口号&#xff0c;为了让客户端额能够找到服务器 3、l…

vsc远程连接centos

1.查看linux系统下的用户名和ip地址 2。安装远程目录 3.远程连接linux下的centos系统 此时说明&#xff1a;已经添加连接成功了&#xff0c;后面只需正常点击连接即可 连接成功

【学习笔记】Matlab和python双语言的学习(图论最短路径)

文章目录 前言一、图论基本概念示例 二、代码实现----Matlab三、代码实现----python总结 前言 通过模型算法&#xff0c;熟练对Matlab和python的应用。 学习视频链接&#xff1a; https://www.bilibili.com/video/BV1EK41187QF?p36&vd_source67471d3a1b4f517b7a7964093e6…