JAVA高并发——CompletableFuture

news2025/2/28 6:23:01

CompletableFuture是Java 8新增的一个超大型工具类。为什么说它大呢?因为它实现了Future接口,而更重要的是,它也实现了CompletionStage接口。CompletionStage接口也是Java 8中新增的,它拥有多达40种方法!是的,你没有看错,这看起来完全不符合设计中所谓的“单方法接口”原则,但是在这里,它就这么存在了。这个接口拥有如此众多的方法,是为函数式编程中的流式调用准备的。通过CompletionStage接口,我们可以在一个执行结果上进行多次流式调用,以得到最终结果。比如,你可以在一个CompletionStage接口上进行如下调用:
在这里插入图片描述
以上一连串的调用会依次执行。

1、完成了就通知我

CompletableFuture和Future一样,可以作为函数调用的契约。向CompletableFuture请求一个数据,如果数据还没有准备好,请求线程就会等待。让人惊喜的是,我们可以手动设置CompletableFuture的完成状态:

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

/**
 * @title AskThread
 * @description CompletableFuture
 * @author: yangyongbing
 * @date: 2024/2/27 8:28
 */
public class AskThread implements Runnable{
    CompletableFuture<Integer> re=null;

    public AskThread(CompletableFuture<Integer> re) {
        this.re = re;
    }

    @Override
    public void run() {
        int myRe=0;
        try {
            myRe=re.get()*re.get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        System.out.println(myRe);
    }

    public static void main(String[] args) throws InterruptedException {
        final CompletableFuture<Integer> future=new CompletableFuture<>();
        new Thread(new AskThread(future)).start();
        // 模拟长时间的计算过程
        Thread.sleep(1000);
        // 告知完成状态
        future.complete(60);
    }
}

在这里插入图片描述
上述代码在第1~17行定义了一个AskThread线程。它接收一个CompletableFuture作为构造函数,它的任务是计算CompletableFuture表示的数字的平方,并将其打印。

代码第20行创建一个CompletableFuture对象实例。第21行,我们将这个对象实例传递给AskThread线程,并启动这个线程。此时,AskThread在执行到第12行代码时会阻塞,因为CompletableFuture中根本没有它所需要的数据,整个CompletableFuture处于未完成状态。第23行用于模拟长时间的计算过程。当计算完成后,可以将最终数据载入CompletableFuture,并标记为完成状态(第25行)。

当第25行代码执行后,表示CompletableFuture已经完成,因此AskThread就可以继续执行了。

2、异步执行任务

通过CompletableFuture提供的进一步封装,我们很容易实现Future模式那样的异步调用,比如:
在这里插入图片描述
上述代码第11~12行使用CompletableFuture.supplyAsync()方法构造一个CompletableFuture实例,在supplyAsync()方法中,它会在一个新的线程中,执行传入的参数。在这里,它会执行calc()方法。而calc()方法的执行可能是比较慢的,但是这不影响CompletableFuture实例的构造速度,因此supplyAsync()方法会立即返回,它返回的CompletableFuture对象实例就可以作为这次调用的契约,将来在任何场合都可以用于获得最终的计算结果。代码第13行试图获得calc()方法的计算结果,如果当前计算没有完成,则调用get()方法的线程就会等待。

在CompletableFuture中,类似的工厂方法如下:
在这里插入图片描述
其中supplyAsync()方法用于那些需要返回值的场景,比如计算某个数据。runAsync()方法用于没有返回值的场景,比如仅仅简单地执行某一个异步动作。

在这两对方法中,都有一个方法可以接收Executor参数。这就使得我们可以让Supplier或者Runnable在指定的线程池中工作。如果不指定线程池,则在默认的系统公共的ForkJoinPool.common线程池中执行。

注意:在Java 8中,新增了ForkJoinPool.commonPool()方法,可以获得一个公共的ForkJoin线程池。这个公共线程池中的所有线程都是Daemon线程,这意味着如果主线程退出,那么这些线程无论是否执行完毕,都会退出系统。

3、流式调用

在前文中我已经提到,CompletionStage的40个方法是为函数式编程做准备的。下面就让我们看一下,如何使用这些方法进行函数式的流式API调用:
在这里插入图片描述
上述代码使用supplyAsync()方法执行一个异步任务。接着连续使用流式调用对任务的处理结果进行再加工,直到最后输出结果。

上述代码使用supplyAsync()方法执行一个异步任务。接着连续使用流式调用对任务的处理结果进行再加工,直到最后输出结果。

在第15行执行CompletableFuture.get()方法,目的是等待calc()方法执行完成。由于CompletableFuture异步执行,如果不进行等待,那么主函数不等calc()方法执行完毕就会退出,随着主线程的结束,所有的Daemon线程都会立即退出,从而会导致calc()方法无法正常完成。

4、CompletableFuture中的异常处理

如果CompletableFuture在执行过程中遇到异常,那么我们可以用函数式编程的风格来优雅地处理这些异常。CompletableFuture提供了一个异常处理方法exceptionally():
在这里插入图片描述
在上述代码中,第8行对当前的CompletableFuture进行异常处理。如果没有异常发生,则CompletableFuture会返回原有的结果。如果遇到了异常,就可以在exceptionally()方法中处理异常,并返回一个默认的值。在上例中,我们忽略了异常堆栈,只是简单地打印异常的信息。

执行上述方法,将得到如下输出:
在这里插入图片描述

5、组合多个CompletableFuture

CompletableFuture还允许你将多个CompletableFuture进行组合。一种组合方法是使用thenCompose()方法,它的签名如下:
在这里插入图片描述
在执行完成后,CompletableFuture可以将执行结果通过Function接口传递给下一个CompletionStage实例进行处理(Function接口返回新的CompletionStage实例):
在这里插入图片描述
上述代码第8行,将处理后的结果传递给thenCompose()方法,并进一步传递给后续新生成的CompletableFuture实例。以上代码的输出如下:
在这里插入图片描述
另外一种组合多个CompletableFuture的方法是thenCombine(),它的签名如下:
在这里插入图片描述
thenCombine()方法首先完成当前CompletableFuture和other的执行,接着将这两者的执行结果传递给BiFunction(该接口接收两个参数,并有一个返回值),并返回代表BiFunction实例的CompletableFuture对象。
在这里插入图片描述
在上述代码中,首先生成两个CompletableFuture实例(第6~7行),接着使用thenCombine()方法组合这两个CompletableFuture,将两者的执行结果进行累加(由第9行的(i, j)->(i+j)实现),并将累加结果转为字符串输出。上述代码的输出是:
在这里插入图片描述

6、支持timeout的CompletableFuture

在JDK 9以后CompletableFuture增加了timeout功能。如果一个任务在给定时间内没有完成,则直接抛出异常。例如:
在这里插入图片描述
本例中CompletableFuture.orTimeout()方法指定Future的执行时间不能超过1秒,如果超过1秒,则抛出TimeoutException异常。在第10行的异常处理中,得到的异常正是由orTimeout()方法抛出的。本例的输出如下:
在这里插入图片描述

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

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

相关文章

大数据职业技术培训包含哪些

技能提升认证考试&#xff0c;旨在通过优化整合涵盖学历教育、职业资格、技术水平和高新技术培训等各种教育培训资源&#xff0c;通过大数据行业政府引导&#xff0c;推进教育培训的社会化&#xff0c;开辟教育培训新途径&#xff0c;围绕大数据技术人才创新能力建设&#xff0…

k8s pv与pvc理解与实践

参考文章&#xff1a; https://blog.csdn.net/qq_41337034/article/details/117220475 一、 pv/pvc简述 Pv是指PersistentVolume&#xff0c;中文含义是持久化存储卷是对底层的共享存储的一种抽象&#xff0c;Pv由管理员进行配置和创建&#xff0c;只要包含存储能力&#xff…

vue3使用elementPlus进行table合并处理

elementPlus中table合并部分列 虚拟数据中公司下有多个客户&#xff0c;公司一样的客户&#xff0c;公司列需要合并&#xff0c;客户如果一样也需要合并进行展示&#xff0c;效果展示 const tableData ref([])自定定义自已想要的数据&#xff0c;一般都是通过接口拿到 //table…

CPU处理器NUMA架构简介

在实际工作中&#xff0c;经常遇到服务器是否开启NUMA、NUMA绑定几颗Core、跨NUMA节点访问的性能下降等等话题。那么NUMA作为非一致性内存访问的多处理器架构&#xff0c;在架构上有什么特性、与SMP架构有哪些不同&#xff0c;调优策略等&#xff0c;本文将作简要介绍。 1、CPU…

什么是SSH端口转发?

目录 前言&#xff1a; 一、SSH端口转发的概念 二、SSH端口转发的类型 2.1 本地端口转发 2.2 远程端口转发 2.3 动态端口转发 三、SSH端口转发的用途 3.1 安全远程访问 3.2 跨越网络限制 3.3 加密流量传输 3.4 跨越 NAT 网络 3.5 安全代理 四、总结 前言&#xff…

设计模式浅析(九) ·模板方法模式

设计模式浅析(九) 模板方法模式 日常叨逼叨 java设计模式浅析&#xff0c;如果觉得对你有帮助&#xff0c;记得一键三连&#xff0c;谢谢各位观众老爷&#x1f601;&#x1f601; 模板方法模式 概念 模板方法模式&#xff08;Template Method Pattern&#xff09;在Java中是…

【MATLAB】VMD_ MFE_SVM_LSTM 神经网络时序预测算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 VMD_MFE_SVM_LSTM神经网络时序预测算法是一种结合了变分模态分解&#xff08;VMD&#xff09;、多尺度特征提取&#xff08;MFE&#xff09;、支持向量机&#xff08;SVM&#xff09;和长…

Java+SpringBoot+Vue+MySQL:美食推荐系统的技术革新

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

启动spark-shell时报错java.lang.NumberFormatException: For input string: “0x100“

一、问题描述 安装完Spark后&#xff0c;启动spark shell时报错 java.lang.NumberFormatException: For input string: "0x100" 如下图&#xff1a; 二、解决办法 1.更换scala的版本 2.更改环境变量 使用vim编辑器打开用户的环境变量配置文件 vim ~/.bashrc s…

解锁财务信任,掌握企业业务合作中的倾听艺术

企业在经营管理过程中&#xff0c;经常会思考如何才能成为一个完美的财务业务融合体&#xff0c;实现业务合作的最大价值。当我们置身于企业战略规划的构建过程中&#xff0c;就会明显的感觉到&#xff0c;获得财务信任有助于指导团队做出重大决策并推动企业未来的行动。市场和…

【蓝桥杯单片机入门记录】动态数码管

目录 一、数码管动态显示概述 二、动态数码管原理图 &#xff08;1&#xff09;原理图 &#xff08;2&#xff09;动态数码管如何与芯片相连 &#xff08;3&#xff09;“此器件” ——>锁存器74HC573 三、动态数码管显示例程 &#xff08;1&#xff09;例程1&#xf…

Day02:Web架构前后端分离站Docker容器站集成软件站建站分配

目录 常规化站点部署 站库分离 前后端分离 集成软件搭建Web应用 Docker容器搭建Web应用 建立分配站 静态 与 伪静态 总结 章节知识点&#xff1a; 应用架构&#xff1a;Web/APP/云应用/三方服务/负载均衡等 安全产品&#xff1a;CDN/WAF/IDS/IPS/蜜罐/防火墙/杀毒等 渗…

react useRef用法

1&#xff0c;保存变量永远不丢失 import React, { useState,useRef } from react export default function App() { const [count,setcount] useState(0) var mycount useRef(0)//保存变量永远不丢失--useRef用的是闭包原理 return( <div> <button onClick{()>…

Linux笔记--硬链接与软链接

一、硬链接 1.inode和block 文件包含两部分数据&#xff1a;文件属性和实际内容&#xff0c;属性放在inode中&#xff0c;实际内容放在data block中。还有个超级区块&#xff08;superblock&#xff09;记录整个文件系统的整体信息&#xff0c;包括inode和block的总量&#x…

%00截断 [GKCTF 2020]cve版签到

打开题目 F12之后在Headers中发现hint 两者结合利用零字符截断使get_headers()请求到本地127.0.0. 结合链接 构造 ?urlhttp://127.0.0.1%00www.ctfhub.com 必须以123结尾 ?urlhttp://127.0.0.123%00www.ctfhub.com 得到flag 知识点&#xff1a; PHP中get_headers函数 g…

合并spark structured streaming处理流式数据产生的小文件

备注&#xff1a; By 远方时光原创&#xff0c;可转载&#xff0c;不能复制到其他平台 背景&#xff1a;做流批一体&#xff0c;湖仓一体的大数据架构&#xff0c;常见的做法就是 数据源->spark Streaming->ODS&#xff08;数据湖&#xff09;->spark streaming->…

如何让网页APP化 渐进式Web应用(PWA)

前言 大家上网应该发现有的网页说可以安装对应应用&#xff0c;结果这个应用好像就是个web&#xff0c;不像是应用&#xff0c;因为这里采用了PWA相关技术。 PWA&#xff0c;全称为渐进式Web应用&#xff08;Progressive Web Apps&#xff09;&#xff0c;是一种可以提供类似…

无法访问云服务器上部署的Docker容器(二)

说明&#xff1a;记录一次使用公网IP 接口地址无法访问阿里云服务接口的问题&#xff1b; 描述 最近&#xff0c;我使用Docker部署了jeecg-boot项目&#xff0c;部署过程都没有问题&#xff0c;也没有错误信息。部署完成后&#xff0c;通过下面的地址访问后端Swagger接口文档…

Facebook的虚拟社交愿景:元宇宙时代的新起点

在当今数字化时代&#xff0c;社交媒体已经成为人们生活中不可或缺的一部分。而随着科技的不断进步和社会的发展&#xff0c;元宇宙已经成为了人们关注的热点话题之一。作为社交媒体的领军企业之一&#xff0c;Facebook也在积极探索虚拟社交的未来&#xff0c;将其视为元宇宙时…

微服务-微服务链路追踪组件Skywalking实战

自动化监控系统Prometheus&Grafana实战&#xff1a; 4 trem APM-性能监控项目班&#xff1a; https://vip.tulingxueyuan.cn/detail/p_602e574ae4b035d3cdb8f8fe/6 1. skywalking是什么 1.1 Skywalking主要功能特性 1.2 Skywalking整体架构 1.3 SkyWalking 环境搭建部…