【并发编程JUC】Future和CompletableFuture机制

news2024/11/23 19:26:26

场景题

面试的时候当面试官提出一个场景题,比如有一个翻译接口,同时调用百度、网易、谷歌的三个翻译接口,使用返回的第一个的翻译。这个时候一般的想法可能是,先串行执行。然后异步获取。但是其实都知道这样性能非常慢。

Future

如果直接使用Future的方式,我们知道Future的get接口是阻塞的,也就是在执行调用三方接口的返回结果的时候,需要阻塞等待结果。
在这里插入图片描述
其实整体的耗时就是取决于最短的三方接口响应,如果百度、网易、google分别是200、300、400毫秒,那么程序需要阻塞200毫秒。

    FutureTask<Integer> futureTask = new FutureTask<Integer>(() -> {
            Thread.sleep(10000);
            System.out.println("调用三方翻译接口");
            return 1024;
        });

        new Thread(futureTask).start();

        Integer integer = futureTask.get(); //会阻塞
        Integer integer = futureTask.get(1, TimeUnit.SECONDS);

        while (true) {
            if (futureTask.isDone()) {
                System.out.println("完成任务");
                break;
            } else {
                System.out.println("执行中,稍等.");
            }
        }
        Integer x = futureTask.get();
        System.out.println(x);

所以在实际的生产环境中,并不会使用get()。而是使用get超时机制,或者使用自定义的isDone() 轮询处理的方式。避免因为一个接口导致整体链路的阻塞。
如果想要异步获取结果,通常都会以轮询的方式去获取结果尽量不要阻塞

在这里插入图片描述
因为Future的继承图是来自Runable,所以启动线程的方式也是通过new Thread的方式开启。

CompletableFuture

为了解决上述Future的阻塞问题点,以及可以实现真正意义上的异步并发编程,所以引入了CompleablteFuture。
在这里插入图片描述

创建方式

## 无 返回值
 public static CompletableFuture<Void> runAsync(Runnable runnable,
                                                   Executor executor) {
        return asyncRunStage(screenExecutor(executor), runnable);
    }

 public static CompletableFuture<Void> runAsync(Runnable runnable) {
        return asyncRunStage(asyncPool, runnable);
    }

## 有返回值
 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
        return asyncSupplyStage(asyncPool, supplier);
    }

public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,
                                                       Executor executor) {
        return asyncSupplyStage(screenExecutor(executor), supplier);
    }

其中executor可以进行自定义的线程池。没有指定Executor的方法,直接使用默认的ForkJoinPool.commonPool() 作为它的线程池执行异步代码。

CompletionStage

CompletionStage描述的是每个子任务,主要包含四个接口,thenApply、thenAccept、thenRun、thenCompose。

描述串行关系

CompletionStage<R> thenApply(fn);
CompletionStage<R> thenApplyAsync(fn);
CompletionStage<Void> thenAccept(consumer);
CompletionStage<Void> thenAcceptAsync(consumer);
CompletionStage<Void> thenRun(action);
CompletionStage<Void> thenRunAsync(action);
CompletionStage<R> thenCompose(fn);
CompletionStage<R> thenComposeAsync(fn);

案例

CompletableFuture<java.lang.String> completableFuture = CompletableFuture.supplyAsync(() -> {
            return "helloword";
        }).thenApply(s -> s + "qq");

需要一个执行完毕,在执行另一个。

描述AND关系

CompletionStage<R> thenCombine(other, fn);
CompletionStage<R> thenCombineAsync(other, fn);
CompletionStage<Void> thenAcceptBoth(other, consumer);
CompletionStage<Void> thenAcceptBothAsync(other, consumer);
CompletionStage<Void> runAfterBoth(other, action);
CompletionStage<Void> runAfterBothAsync(other, action);

描述 OR 汇聚关系

CompletionStage applyToEither(other, fn);
CompletionStage applyToEitherAsync(other, fn);
CompletionStage acceptEither(other, consumer);
CompletionStage acceptEitherAsync(other, consumer);
CompletionStage runAfterEither(other, action);
CompletionStage runAfterEitherAsync(other, action);

异常处理

CompletionStage exceptionally(fn);
CompletionStage<R> whenComplete(consumer);
CompletionStage<R> whenCompleteAsync(consumer);
CompletionStage<R> handle(fn);
CompletionStage<R> handleAsync(fn);

案例

     CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + " 异步调用三方");
            try {
                Thread.sleep(TimeUnit.SECONDS.toSeconds(10));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 1;
        }).thenApply(f -> {
            return f + 10;
        }).whenComplete((v, e) -> {
            if (e == null) {
                System.out.println("计算结果为:" + v);
            }
        }).exceptionally(e -> {
            e.printStackTrace();
            return null;
        });

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

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

相关文章

Baumer工业相机堡盟工业相机如何通过BGAPISDK设置相机的固定帧率(C#)

Baumer工业相机堡盟工业相机如何通过BGAPI SDK设置相机的固定帧率&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机的固定帧率功能的技术背景CameraExplorer如何查看相机固定帧率功能在BGAPI SDK里通过函数设置相机固定帧率 Baumer工业相机通过BGAPI SDK设置相机固定帧…

【Linux系统编程】22.exec函数、execlp、execl、execvp

目录 exec函数 execlp 参数file 返回值 测试代码1 测试结果 execl 测试代码2 测试结果 execvp 测试代码3 测试结果 exec函数 fork创建子进程后执行的是和父进程相同的程序&#xff0c;但有可能执行不同的代码分支&#xff0c;子进程往往要调用一种exec函数以执行另…

如何在Vue2.X/Vue3.X项目引入jQuery,以及增加jQuery.easing扩展?让你的动画效果更加丝滑!

前言 还记得在2015左右&#xff0c;网页开发依然是jQuery的天下&#xff0c;虽然Vue、React开始盛行&#xff0c;以及后面Angular也开始抢占市场&#xff0c;但是jQuery在市场上依然占有较大的比重。当时的html页面大多是用jQuery来写的&#xff0c;为jQuery设计的插件也是相当…

应用层协议——TCP(上)

文章目录 1. TCP协议1.1 TCP协议段格式1.2 确认应答(ACK)机制1.3 16位窗口大小1.4 6位标志位1.4.1 TCP三次握手 1.5 确认应答(ACK)机制1.6 超时重传机制1.7 连接管理机制1.7.1 理解TIME_WAIT状态1.7.2 理解 CLOSE_WAIT 状态 1. TCP协议 TCP全称为传输控制协议&#xff0c;意思…

双端口存储器原理实验

1.实验目的及要求 1.1实验目的 1&#xff09;了解双端口静态随机存储器IDT7132的工作特性及使用方法。 2&#xff09;了解半导体存储器怎样存储和读出数据。 3&#xff09;了解双端口存储器怎样并行读写&#xff0c;并分析冲突产生的情况。 1.2实验要求 1&#xff09;做好…

百度屏蔽词有哪些?其中就有移民关键词指数被屏蔽?

我是百收网SEO&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 今日tombkeeper消息爆料&#xff1a;百度指数已经屏蔽“移民”等关键词指数。 大家好&#xff0c;我是百收网SEO商学院的狂潮微课老师&#xff0c;今天我们来讲解第 12 节课关键词优化难度分析…

JZ39数组中出现次数超过一半的数字

题目地址&#xff1a;数组中出现次数超过一半的数字_牛客题霸_牛客网 题目回顾&#xff1a; 解题思路&#xff1a; 最简单用哈希表来记录每个数字在数组中出现的次数&#xff0c;在遍历这个数组时同时进行判断是否满足条件。 整体代码&#xff1a; public int MoreThanHalfNum…

腾讯云服务器竞价实例是什么意思?CVM计费模式选择说明

腾讯云服务器CVM计费模式分为包年包月、按量计费和竞价实例&#xff0c;什么是竞价实例&#xff1f;竞价实例和按量付费相类似&#xff0c;优势是价格更划算&#xff0c;缺点是云服务器实例有被自动释放风险&#xff0c;腾讯云服务器网来详细说下什么是竞价实例&#xff1f;以及…

【MySQL】MySQL不走索引的情况分析

未建立索引 当数据表没有设计相关索引时&#xff0c;查询会扫描全表。 create table test_temp (test_id int auto_incrementprimary key,field_1 varchar(20) null,field_2 varchar(20) null,field_3 bigint null,create_date date null );expl…

C++多态与虚函数的原理与关系

C多态 多态可以分为编译时的多态和运行时的多态。前者主要是指 函数的重载&#xff08;包括运算符的重载&#xff09;、对重载函数的调用&#xff0c;在编译时就能根据实参确定应该调用哪个函数&#xff0c;因此叫编译时的多态&#xff1b;而后者则和继承、虚函数等概念有关。…

智慧交通项目实战全流程-DeepSort多目标跟踪车道线检测

1. 项目介绍 2. 算法库 2.1 numba介绍 numba是⼀个⽤于编译Python数组和数值计算函数的编译器&#xff0c;这个编译器能够⼤幅提⾼直接使⽤Python编写的函数的运算速度。 使用方法 numba对代码进⾏加速时&#xff0c;给要优化的函数加上jit优化器即可。使⽤jit的时候可以让…

IDEA断点调试(debug)

目录 1.断点调试介绍 2.F8逐行执行代码 3.调试遇异常 4.调试时如何看源码 5.如何直接执行到下一个断点 F9 6.利用断点调试查看动态绑定机制 1.断点调试介绍 断点调试是指在程序的某一行设置一个断点&#xff0c;调试时&#xff0c;程序运行到这一 行就会停住&#xff0…

2023年国赛数学建模思路 - 案例:FPTree-频繁模式树算法

文章目录 算法介绍FP树表示法构建FP树实现代码 建模资料 ## 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 算法介绍 FP-Tree算法全称是FrequentPattern Tree算法&#xff0c;就是频繁模式树算法&#xff0c…

【Rust日报】2023-08-11 candle:一个极简的Rust机器学习框架

Bevys Third Birthday Bevy 是一个用 Rust 构建的令人耳目一新的数据驱动的游戏引擎&#xff0c;如果你想学习如何使用 Bevy 制作 2D/3D 游戏、可视化、用户界面或其他图形应用程序&#xff0c;那可以访问Bevy官网去了解更多。 阅读原文&#xff1a;https://bevyengine.org/new…

GPU Microarch 学习笔记 [1]

WARP GPU的线程从thread grid 到thread block&#xff0c;一个thread block在CUDA Core上执行时&#xff0c;会分成warp执行&#xff0c;warp的颗粒度是32个线程。比如一个thread block可能有1024个线程&#xff0c;分成32个warp执行。 上图的CTA&#xff08;cooperative thre…

西门子PLC模拟量接线及程序

接线 2线制接线 3线制接线 4线制接线 程序 指令 S_ITR 输入参数 EN 使能信号 AIW0 模拟量通道 ISH ISL 0-20ma对应 0-32000 4-20ma 对应 6400-32000 OSH OSL 传感器的测量值的最大和最小值 300 和 -50 输出参数 VD0 当前的测量温度

docker部署springboot

基础知识 什么是docker 官网&#xff1a; Docker Docs: How to build, share, and run applications | Docker Documentation Docker 是一个基于go语言开发的开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到…

Unity 鼠标实现对物体的移动、缩放、旋转

文章目录 1. 代码2. 测试场景 1. 代码 using UnityEngine;public class ObjectManipulation : MonoBehaviour {// 缩放比例限制public float MinScale 0.2f;public float MaxScale 3.0f;// 缩放速率private float scaleRate 1f;// 新尺寸private float newScale;// 射线pri…

简绘ChatGPT支持Midjourney绘图 支持stable diffusion绘图

简绘支持Midjourney绘图和stable diffusion绘图。 这意味着简绘具备Midjourney绘图和stable diffusion绘图功能的支持。