CompletableFuture:Java中的异步编程利器

前言:

在秋招的面试中,面试官问了很多关于异步编程相关的知识点,朋友最近也和我聊到了这个话题,因此今天咱们来讨论讨论这个知识点!

随着现代软件系统的日益复杂,对于非阻塞性和响应性的需求也在不断增加。Java为我们提供了多种工具和技术来满足这些需求,其中CompletableFuture便是Java 8中引入的一种强大的异步编程工具。
在这里插入图片描述

文章目录

  • CompletableFuture的底层机制
  • CompletableFuture的核心工作流程
  • CompletableFuture应用场景
    • 非阻塞性I/O操作
    • 用于并行计算
    • 组合异步操作
    • 错误处理
  • CompletableFuture小结

CompletableFuture的底层机制

在深入了解CompletableFuture之前,我们首先需要理解什么是Future(在这里不是未来的意思哦😁)。

在Java中,Future代表一个异步计算的结果。这意味着我们可以使用Future来查询计算是否完成(isDone()),或者阻塞当前线程,直到计算完成并返回结果(get())。然而,Future并不提供直接的方法来处理计算完成后的结果或异常。

这就是CompletableFuture的闪亮之处。与Future不同,CompletableFuture实现了CompletionStage接口,这意味着它提供了更为丰富和灵活的API来处理异步计算的结果或异常。例如,我们可以使用thenApply(), thenAccept(), thenRun()和exceptionally()等方法来添加回调函数。

CompletableFuture的核心工作流程

当我们创建一个CompletableFuture实例时,它代表了一个尚未完成的异步计算。这个异步计算可以在另一个线程中执行,也可以由线程池执行。一旦计算完成,结果就会被存储在CompletableFuture实例中。任何等待这个结果的线程(通过调用get()或相关方法)都会被唤醒并返回结果。

除此,我们还可以链式地添加多个回调函数来处理结果或异常。这些回调函数只会在计算完成后被调用,并且它们自己也是异步执行的。这意味着我们可以避免阻塞主线程,同时确保代码的逻辑连续性

在这里插入图片描述

CompletableFuture应用场景

下面介绍一下CompletableFuture在项目中的几个经典应用场景。

非阻塞性I/O操作

当我们执行I/O密集型任务,比如读取文件、网络请求,使用CompletableFuture可以确保主线程不会被阻塞,从而提高应用的响应性。

public class AsyncFileIO {  public static void main(String[] args) throws Exception {  CompletableFuture<String> fileContentFuture = CompletableFuture.supplyAsync(() -> {  try {  return new String(Files.readAllBytes(Paths.get("xiaowei.txt")));  } catch (Exception e) {  throw new RuntimeException("Error reading file", e);  }  });  // 在文件读取完成前,可以执行其他操作...  // ...  其他操作// 等待文件读取完成并处理内容  String fileContent = fileContentFuture.get();  System.out.println("File content: " + fileContent);  }  
}

用于并行计算

对于可以并行处理的任务,你可以创建多个CompletableFuture实例并在不同的线程或线程池中执行它们。然后,你可以使用allOf()或anyOf()方法来等待所有或部分任务完成。

public class CompletableFutureDemo {  public static void main(String[] args) {  CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> compute(100));  CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> compute(200));  CompletableFuture<Integer> combinedFuture = future1.thenCombine(future2, (result1, result2) -> result1 + result2);  Integer sum = combinedFuture.join(); // 等待所有future完成并获取结果  System.out.println("Sum: " + sum);  }  private static int compute(int value) {  // 模拟长时间计算...  return Stream.iterate(0, i -> i + 1)  .limit(value)  .mapToInt(i -> i)  .sum();  }  
}

组合异步操作

有时我们可能需要等待多个异步操作完成后才能继续。使用CompletableFuture.allOf()可以轻松实现这一点。例如:

CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");  
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "World");  
CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(future1, future2);  
combinedFuture.join(); // 等待所有future完成

错误处理

与传统的Future相比,CompletableFuture提供了更为优雅的错误处理方式。你可以使用exceptionally()方法来处理异步操作中抛出的异常。例如:

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {  // 可能抛出异常的长时间运行的任务  return someLongRunningTask();  
}).exceptionally(ex -> {  // 处理异常并返回默认值  return handleException(ex);  
});

在这里插入图片描述

CompletableFuture小结

尽管CompletableFuture非常强大,但是过度使用它可能会导致代码变得复杂和难以维护。确保只在真正需要异步处理的地方使用它。

当使用线程池与CompletableFuture相结合的时候,要确保正确配置线程池的大小和参数,以避免资源耗尽或性能下降。

所以,异步编程虽然好用,但也带来了更多的复杂性和不确定性。还望各位佬在使用时需谨慎!

文章到这里就先结束了,感兴趣的可以订阅专栏哈,后续会继续分享相关的知识点。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/203893.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

3 文本分类入门finetune:bert-base-chinese

项目实战&#xff1a; 数据准备工作 bert-base-chinese 是一种预训练的语言模型&#xff0c;基于 BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;架构&#xff0c;专门用于中文自然语言处理任务。BERT 是由 Google 在 2018 年提出的一…

gpt1与bert区别

区别1&#xff1a;网络结构&#xff08;主要是Masked Multi-Head-Attention和Multi-Head-Attention&#xff09; gpt1使用transformer的decoder&#xff0c;单向编码&#xff0c;是一种基于语言模型的生成式模型&#xff0c;更适合生成下一个单词或句子 bert使用transformer的…

Domino多Web站点托管

大家好&#xff0c;才是真的好。 看到一篇文档&#xff0c;大概讲述的是他在家里架了一台Domino服务器&#xff0c;上面跑了好几个Internet的Web网站&#xff08;使用Internet站点&#xff09;。再租了一台云服务器&#xff0c;上面安装Nginx做了反向代理&#xff0c;代理访问…

轨迹分析:Palantir评估细胞分化潜能 类似于monocle2

轨迹分析是单细胞测序分析中重要的组成部分&#xff0c;它基于细胞谱系之间“具有中间态细胞”的理论基础&#xff0c;通过结合先验知识&#xff08;细胞注释、markers&#xff09;、细胞基因表达改变等&#xff0c;为在单细胞测序数据赋予了“假时间”&#xff08;pseudotime&…

图的深度优先搜索(数据结构实训)

题目&#xff1a; 图的深度优先搜索 描述&#xff1a; 图的深度优先搜索类似于树的先根遍历&#xff0c;是树的先根遍历的推广。即从某个结点开始&#xff0c;先访问该结点&#xff0c;然后深度访问该结点的第一棵子树&#xff0c;依次为第二顶子树。如此进行下去&#xff0c;直…

每天五分钟计算机视觉:通过残差块搭建卷积残差神经网络Resnet

本文重点 随着深度神经网络的层数的增加,神经网络会变得越来越难以训练,之所以这样就是因为存在梯度消失和梯度爆炸问题。本节课程我们将学习跳跃连接方式,它可以从某一网络层获取激活a,然后迅速反馈给另外一层,甚至是神经网络的更深层,从而解决梯度消失的问题。 传统的…

关于命令行方式的MySQL服务无法启动问题原因之一解决

这里无法启动服务的原因为系统某些进行占用了3306端口问题 当你遇到无法启动的问题时&#xff0c;可以尝试通过netstat -ano命令查看系统进行信息&#xff0c;验证是否3306端口被占用 在本地地址列如果发现3306端口被占用&#xff0c;则通过 taskkill /f /pid 进程id命令关闭进…

matlab 点云放缩变换

目录 一、算法原理二、代码实现三、结果展示四、相关链接本文由CSDN点云侠原创,原文链接。爬虫网站自重。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法原理 缩放可以独立应用于三个坐标轴,如将点 ( x , y , z ) ( x

dtm分布式事务框架之SAGA 实战

一.dtm分布式事务框架之SAGA 1.1DTM介绍 DTM是一款开源的分布式事务管理器&#xff0c;解决跨数据库、跨服务、跨语言栈更新数据的一致性问题。 通俗一点说&#xff0c;DTM提供跨服务事务能力&#xff0c;一组服务要么全部成功&#xff0c;要么全部回滚&#xff0c;避免只更…

【天线了解】1.004天线的了解以及使用

一。004天线使用步骤 1.打开天线 &#xff08;1&#xff09;天线的各种版本 注意&#xff1a; 《1》天线包括单通道天线程序&#xff0c;双通道天线程序等。 《2》在没有连接天线时&#xff0c;有的天线程序打不开。 &#xff08;2&#xff09;打开软件前的配置工作 注意&…

接鸡冠^^

欢迎来到程序小院 接鸡冠 玩法&#xff1a;左右移动棒棒君(小海豹)接住鸡冠&#xff0c;避开炸弹&#xff0c;若不小心接住炸弹则游戏结束&#xff0c; 赶紧接鸡冠吧&#xff0c;看看你能够接住多少鸡冠哦^^。。开始游戏https://www.ormcc.com/play/gameStart/211 html <di…

【精选】设计模式——策略设计模式-两种举例说明,具体代码实现

Java策略设计模式 简介 策略设计模式是一种行为型设计模式&#xff0c;它允许在运行时选择算法的行为。 在软件开发中&#xff0c;我们常常需要根据不同情况采取不同的行为。通常的做法是使用大量的条件语句来实现这种灵活性&#xff0c;但这会导致代码变得复杂、难以维护和扩…

Unity打包EXE自定义(拖拽)窗口大小

代码 using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using System.Runtime.InteropServices; public class MyWindow : MonoBehaviour {[DllImport("user32.dll")]private static extern IntPtr GetActiveWindow(…

CSS-自适应导航栏(flex | grid)

目标&#xff1a;实现左右各有按钮&#xff0c;中间是内容&#xff0c;自适应显示中间的内容导航栏&#xff0c;即 根据中间的宽度大小显示内容。 自适应导航栏 总结&#xff1a;推荐 flex布局 / grid布局 flex布局&#xff1a; 两侧 flex:1; ----->中间自适应 grid布局&…

uniapp(微信小程序)聊天实例,支持图片,语音,表情(附源码)

效果预览 安装教程 配置 请参考Dome 会话配置 {info:{// 用户关键字userKey:2666,// 用户手机userPhone:15252156614,// 用户昵称userName: 健健,// 头像headImg: http://d.hiphotos.baidu.com/image/h%3D300/sign0defb42225381f3081198ba999004c67/6159252dd42a2834a75bb01…

CRM客户关系管理系统的主要功能有哪些?

我们都知道&#xff0c;CRM系统可以帮助企业加快业务增长。如果一个企业能提高业务效率、跨团队协作、有效管理客户、轻松共享和同步数据&#xff0c;那么企业竞争力将极大地提高。基于此&#xff0c;我们说说CRM客户关系管理系统的主要功能分析。 完整的CRM是什么样的&#x…

红队专题-开源资产扫描系统-ARL资产灯塔系统

ARL资产灯塔系统 安装说明问题 &#xff1a; 安装说明 源码地址 https://github.com/TophantTechnology/ARL https://github.com/TophantTechnology/ARL/wiki/Docker-%E7%8E%AF%E5%A2%83%E5%AE%89%E8%A3%85-ARL 安装环境 uname -a Linux VM-24-12-centos 3.10.0-1160.49.1.e…

亚马逊云科技re:Invent,生成式AI正在彻底改变开发者的工作方式

去年此时&#xff0c;ChatGPT横空出世席卷全球&#xff0c;许多人称其意味着AI的iPhone时刻到来。CSDN创始人蒋涛对此曾预测&#xff1a;「下一步就是应用时刻&#xff0c;新应用时代将来临……大模型将推动更多的AI应用程序员诞生」。 在2023亚马逊云科技re:Invent全球大会第三…

Linux--环境变量

一.基本概念 * 环境变量 (environment variables) 一般是指在操作系统中用来指定操作系统运行环境的一些参数 * 如&#xff1a;我们在编写 C/C 代码的时候&#xff0c;在链接的时候&#xff0c;从来不知道我们的所链接的动态静态库在哪里&#xff0c;但 是照样可以链接成功&am…

使用jenkins插件Allure生成自动化测试报告

前言 以前做自动化测试的时候一直用的HTMLTestRunner来生成测试报告&#xff0c;后来也尝试过用Python的PyH模块自己构建测试报告&#xff0c;在后来看到了RobotFramework的测试报告&#xff0c;感觉之前用的测试报告都太简陋&#xff0c;它才是测试报告应该有的样子。也就是在…