CompletableFuture 和 Future 的选择,以及CompletableFuture的用法

news/2024/9/20 2:58:09

在 Java 编程中,异步编程是一种重要的技术,它允许你在执行长时间运行的任务时不会阻塞主线程。为了支持异步编程,Java 提供了 FutureCompletableFuture 这两个关键的类。在本文中,我们将比较它们的特点、优缺点以及使用场景。

Future 的特点:
  1. 特点

    • Future 是 Java 5 引入的接口,用于表示一个异步计算的结果。
    • Future 可以通过 get 方法来获取异步操作的结果,但该方法是阻塞的,如果异步操作未完成,它会一直等待。
    • Future 不提供一种直接的方式来添加回调函数,处理操作完成后的结果或异常。
    • Future 只能表示异步任务是否完成,而不能手动触发任务的完成或组合多个任务。
  2. 优点

    • 简单易用,适用于基本的异步操作。
  3. 缺点

    • 阻塞问题:get 方法会阻塞当前线程,如果异步任务很慢或永远不完成,会导致程序出现长时间阻塞。
    • 缺乏异步编程的灵活性:难以编写复杂的异步代码,例如组合多个异步任务或处理异常。
  4. 使用场景

    • 适用于简单的异步任务,不需要处理复杂的回调或组合多个任务的结果。
CompletableFuture 的特点:
  1. 特点

    • CompletableFuture 是 Java 8 引入的类,是 Future 的增强版。
    • 支持非阻塞的异步操作,可以使用回调函数(例如 thenApplythenCompose)来处理操作完成后的结果。
    • 可以手动触发任务的完成,使得编写自定义的异步逻辑更加灵活。
    • 支持组合多个异步任务的结果。
  2. 优点

    • 异步编程更加灵活和强大,可以处理复杂的异步操作。
    • 可以避免阻塞,提高程序性能。
  3. 缺点

    • 学习曲线较陡峭,相对复杂,需要更多的理解和实践。
    • 需要小心管理线程池和资源,以避免资源泄漏或性能问题。
  4. 使用场景

    • 适用于复杂的异步编程场景,需要组合多个异步任务,处理异常,或者避免阻塞。
    • 需要更多控制和灵活性的情况,如超时处理、异步事件处理等。

CompletableFuture 的使用方法:

现在让我们深入了解一下 CompletableFuture 的使用方法。

创建 CompletableFuture:

你可以使用不同的方式创建 CompletableFuture 对象,最常见的是使用 CompletableFuture.supplyAsyncCompletableFuture.runAsync 方法,这些方法接受一个 SupplierRunnable 作为参数,并返回一个 CompletableFuture 对象。

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 42);
CompletableFuture<Void> futureVoid = CompletableFuture.runAsync(() -> doSomething());
异步操作:

CompletableFuture 允许你执行异步操作,这些操作不会阻塞当前线程。你可以将需要执行的操作包装在 CompletableFuture 中,然后使用 thenApplythenComposethenAccept 等方法来定义操作完成后的回调。

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 42);
CompletableFuture<String> futureResult = future.thenApply(result -> "Result: " + result);
组合 CompletableFuture:

你可以将多个 CompletableFuture 组合在一起,以便在它们都完成时执行某个操作,或者在其中任何一个完成时执行某个操作。这可以使用 thenCombinethenComposethenCombineAsync 等方法来实现。

CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 42);
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 23);
CompletableFuture<Integer> combinedFuture = future1.thenCombine(future2, (result1, result2) -> result1 + result2);
异常处理:

CompletableFuture 允许你处理异步操作中可能发生的异常。你可以使用 exceptionallyhandle 方法来捕获和处理异常。

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
   // Simulate an exception
   throw new RuntimeException("Error!");
});

CompletableFuture<Integer> resultFuture = future.exceptionally(ex -> {
   System.out.println("Caught exception: " + ex.getMessage());
   return 0; // Provide a default value
});
等待 CompletableFuture 完成:

你可以使用 get 方法等待 CompletableFuture 的完成,但要小心,因为它会阻塞当前线程,直到任务完成。

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 42);
try {
   Integer result = future.get();
   System.out.println("Result: " + result);
} catch (Exception e) {
   // Handle exceptions
}
组合多个 CompletableFuture:

使用 CompletableFuture.allOfCompletableFuture.anyOf 可以组合多个 CompletableFuture,以等待它们全部完成或任何一个完成。

CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 42);
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 23);

CompletableFuture<Void> allOfFuture = CompletableFuture.allOf(future1, future2);
CompletableFuture<Object> anyOfFuture = CompletableFuture.anyOf(future1, future

http://lihuaxi.xjx100.cn/news/1595755.html

相关文章

SQL按照id集合顺序返回

SQL按照id集合顺序返回 一、需求二、SQL三、MyBatis编写四、FIELD函数五、环境 一、需求 sql这样的 SELECT id, name FROM is_parent_viewshop WHERE id IN (2350, 2396, 3768, 3718, 3692) 按照id顺序返回&#xff0c;sql如何写 二、SQL SELECT id, name FROM is_parent_vi…

测试的java pom.xml【搬代码】

个人java代码中的pom文件内容 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.a…

【UE】在游戏运行时,通过选择uasset来生成静态网格体

目录 主要流程 步骤 一、创建用于包含静态网格体的Actor蓝图 二、按钮点击事件 效果 主要流程 用户点击按钮后产生一个文件对话框&#xff0c;用户通过文件对话框选择指定的文件夹&#xff0c;我们获取到这个文件夹路径后处理成“按路径获取资产”节点所需的输入&#x…

React xlsx(工具库) 处理表头合并

前端导出excel表格 引入xlsx插件&#xff0c;不然应该是运行不起来的 npm i xlsx xlsx中文文档 插件2 exceljs npm i exceljs exceljs中文文档 导出 例子 import { ExportExcel } from ./exportExcel/index;const columns[{title: id,dataIndex: item1,},{title: 序号,dataInd…

代码随想录算法训练营第23期day11 | 20. 有效的括号、1047. 删除字符串中的所有相邻重复项 、150. 逆波兰表达式求值

目录 一、&#xff08;leetcode 20&#xff09;有效的括号 二、&#xff08;leetcode 1047&#xff09;删除字符串中的所有相邻重复项 用栈存放 将字符串直接当成栈 三、&#xff08;leetcode 150&#xff09;逆波兰表达式求值 一、&#xff08;leetcode 20&#xff09;…

【Spring Boot 源码学习】OnWebApplicationCondition 详解

Spring Boot 源码学习系列 OnWebApplicationCondition 详解 引言往期内容主要内容1. getOutcomes 方法2. getMatchOutcome 方法3. isWebApplication 方法3.1 isServletWebApplication 方法3.2 isReactiveWebApplication 方法3.3 isAnyWebApplication 方法 总结 引言 上篇博文带…

Vue Router的使用

使用 项目中注入路由器 在项目中 src 目录下新建 router 目录&#xff0c;其中包含 index.js 路由主文件。 // src/router/index.jsimport Vue from vue import Router from vue-router import { routes } from ./routes.jsVue.use(Router) const router new Router({route…

一座“城池”:泡泡玛特主题乐园背后,IP梦想照亮现实

“更适合中国宝宝体质”的主题乐园&#xff0c;被泡泡玛特造出来了。 9月26日&#xff0c;位于北京朝阳公园内的国内首个潮玩行业沉浸式 IP 主题乐园&#xff0c;也是泡泡玛特首个线下乐园——泡泡玛特城市乐园 POP LAND正式开园。 约4万平方米的空间中&#xff0c;泡泡玛特使…