CompletableFuture-应用

在这里插入图片描述
可以看到CompletableFuture实现了CompletionStage 和Future的两个接口。CompletionStage提供了任务之间的衔接能力,而Future则是经常用于阻塞获取结果。

CompletableFuture 的内部使用了基于 ForkJoinPool 的线程池,这种线程池可以高效地调度和执行任务。CompletableFuture 的非阻塞特性得益于其对任务完成的监听机制。当任务完成时,它会遍历所有注册的回调函数,并在合适的线程中执行这些回调。通过这种机制,CompletableFuture 能够在任务完成后及时返回结果或触发后续处理逻辑,而不会阻塞主线程的执行。

使用场景

场景一 并行执行多个任务
public class FutureDemo {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        CompletableFuture<Void> f1 = CompletableFuture.runAsync(() -> {
            task1();
        });
        CompletableFuture<Void> f2 = CompletableFuture.runAsync(() -> {
            task2();
        });
        CompletableFuture<Void> f3 = CompletableFuture.runAsync(() -> {
            task3();
        });
        CompletableFuture<Void> allOf = CompletableFuture.allOf(f1, f2, f3);
        try {
        	// 所有任务一起并行
            allOf.get();
            System.out.println("all task finish cost:" + (System.currentTimeMillis() - start));
        } catch (InterruptedException e) {

        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }
        System.out.println("main thread finsh!!!");


    }

    public static void task1() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("task1 finish cost 3000!!!");
    }

    public static void task2() {
        try {
            Thread.sleep(6000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("task2 finish cost 6000!!!");
    }

    public static void task3() {
        try {
            Thread.sleep(9000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("task3 finish cost 9000!!!");
    }
}

可以看到运行结果,多个任务并行执行,总任务完成时间是耗时最长的任务:
在这里插入图片描述

场景一 父任务执行完毕以后 开启多个子任务
public class FutureDemo {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        try {
            CompletableFuture<Void> f1 = CompletableFuture.runAsync(() -> {
                task1();
            });
            // 任务一执行完毕
            f1.get();
            CompletableFuture<Void> f2 = CompletableFuture.runAsync(() -> {
                task2();
            });
            CompletableFuture<Void> f3 = CompletableFuture.runAsync(() -> {
                task3();
            });
            CompletableFuture<Void> allOf = CompletableFuture.allOf(f2, f3);
            // 任务2,3并行
            allOf.get();
            System.out.println("all task finish cost:" + (System.currentTimeMillis() - start));
        } catch (InterruptedException e) {

        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }
        System.out.println("main thread finsh!!!");
    }

    public static void task1() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("task1 finish cost 3000!!!");
    }

    public static void task2() {
        try {
            Thread.sleep(6000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("task2 finish cost 6000!!!");
    }

    public static void task3() {
        try {
            Thread.sleep(9000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("task3 finish cost 9000!!!");
    }
}

在这里插入图片描述
由于第一个任务阻塞执行完毕,2,3任务并行执行,时间最长的执行了9秒所以总时间是12左右。

场景三 场景一的变种

A B
C
我们希望A和C都执行完以后继续往后执行,并且C的执行顺序严格在B以后。

public class FutureDemo {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        try {
            CompletableFuture<Void> f1 = CompletableFuture.runAsync(() -> {
                task1();
            });

            CompletableFuture<Void> f2 = CompletableFuture.runAsync(() -> {
                task2();
            });
            CompletableFuture<Void> f3 = f2.thenRunAsync(() -> {
                task3();
            });
            CompletableFuture<Void> allOf = CompletableFuture.allOf(f1, f3);
            allOf.get();
            System.out.println("all task finish cost:" + (System.currentTimeMillis() - start));
        } catch (InterruptedException e) {

        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }
        System.out.println("main thread finsh!!!");
    }

    public static void task1() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("task1 finish cost 3000!!!");
    }

    public static void task2() {
        try {
            Thread.sleep(6000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("task2 finish cost 6000!!!");
    }

    public static void task3() {
        try {
            Thread.sleep(9000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("task3 finish cost 9000!!!");
    }
}

在这里插入图片描述
由于任务一是一个任务,而任务2和3是一起执行,所以相当于是两个任务并行,时间最长是任务2,3加在一起。

场景四 任取其一

这种场景什么时候使用呢?比如我们对数处理做了不同的策略,我们不知道哪个计算的速度更快,我们希望谁先出结果就优先使用。

public class FutureDemo {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        try {
            CompletableFuture<Void> f1 = CompletableFuture.runAsync(() -> {
                task1();
            });
            CompletableFuture<Void> f2 = CompletableFuture.runAsync(() -> {
                task2();
            });
            CompletableFuture<Void> f3 = CompletableFuture.runAsync(() -> {
                task3();
            });
            CompletableFuture<Object> anyOf = CompletableFuture.anyOf(f1, f2, f3);
            // 任务2,3并行
            anyOf.get();
            System.out.println("all task finish cost:" + (System.currentTimeMillis() - start));
        } catch (InterruptedException e) {

        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }
        System.out.println("main thread finsh!!!");
    }

    public static void task1() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("task1 finish cost 3000!!!");
    }

    public static void task2() {
        try {
            Thread.sleep(6000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("task2 finish cost 6000!!!");
    }

    public static void task3() {
        try {
            Thread.sleep(9000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("task3 finish cost 9000!!!");
    }
}

在这里插入图片描述
可以看到这里肯定是耗时最短的任务1先执行完毕,所以 总耗时为3秒。
参考资料:
https://www.yuque.com/itlaoqi/uprrn9/nakraehf13w4xdy4

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WPF如何获取DataGrid的选中行

在DataGrid中加入这一行 <MouseBindingCommand"{Binding OpenWindowCommand}"CommandParameter"{Binding ElementNameNewPlanDataGrid, PathSelectedItem}"Gesture"LeftDoubleClick" /> </DataGrid.InputBindings> 然后ViewModel中…

与AI共创未来:Blackbox AI让工作更轻松

一、前言 还在为如何提升工作效率而烦恼吗&#xff1f;让 Blackbox AI 帮助你解锁全新生产力&#xff01;Blackbox AI 是一个功能强大的AI平台&#xff0c;集成了多种智能GPT对话助手和智能代码插件&#xff0c;专为满足现代工作的多样需求而设计。不管是在处理文本生成、数据…

ubuntu查看CPU、内存、硬盘

1、查看CPU cat /proc/cpuinfo 我这台机器CPU是2核&#xff0c;所以这里是2核 或者使用如下命令也可以查看 lscpu 查看CPU使用率 top 2、查看内存 查看内存信息&#xff1a; free -h 查看内存使用情况&#xff1a; vmstat 3、硬盘 查看硬盘使用情况&#xff1a; df -…

用IDEA创建Servlet实例

一.首先&#xff0c;Servlet是什么&#xff1f; &#x1f379;参考博文&#xff1a;servlet介绍 &#x1f387;参考视频&#xff1a;servlet原理 &#x1f340;参考网站&#xff1a;servlet教程 下图的web容器可以理解为tomcat服务器&#xff0c;servlet就是用来处理w…

计算机毕业设计 公寓出租系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

SQL— DQL语句学习【后端 11】

DQL语句 引言 DQL&#xff08;Data Query Language&#xff0c;即数据查询语言&#xff09;是SQL&#xff08;Structured Query Language&#xff09;中用于从数据库中检索数据的重要部分。在数据库管理中&#xff0c;DQL语句是日常工作中最常用的工具之一。通过DQL&#xff0…

三千元左右的卧室投影仪怎么选?当贝D6X Pro代替电视的最佳选择

想象一下&#xff0c;在舒适的卧室中&#xff0c;只需轻轻一瞥&#xff0c;便能享受一场视觉盛宴&#xff0c;无需起身&#xff0c;天花板即成为你的私人影院。这一梦想现已成真&#xff0c;只需挑选一台合适的卧室投影仪&#xff0c;即可实现这一愿望。 下面是2024年卧室投影仪…

基于UE5和ROS2的激光雷达+深度RGBD相机小车的仿真指南(二)---ROS2与UE5进行图像数据传输

前言 本系列教程旨在使用UE5配置一个具备激光雷达深度摄像机的仿真小车&#xff0c;并使用通过跨平台的方式进行ROS2和UE5仿真的通讯&#xff0c;达到小车自主导航的目的。本教程默认有ROS2导航及其gazebo仿真相关方面基础&#xff0c;Nav2相关的学习教程可以参考本人的其他博…

C++实现——红黑树

目录 1.红黑树 1.1红黑树的概念 1.2红黑树的性质 1.3红黑树节点的定义 1.4红黑树的插入操作 1.5红黑树的验证 1.6红黑树的删除 1.7红黑树与AVL树的比较 1.8红黑树的应用 1.红黑树 1.1红黑树的概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存储位…

leetcode67. 二进制求和,简单模拟

leetcode67. 二进制求和 给你两个二进制字符串 a 和 b &#xff0c;以二进制字符串的形式返回它们的和。 示例 1&#xff1a; 输入:a “11”, b “1” 输出&#xff1a;“100” 示例 2&#xff1a; 输入&#xff1a;a “1010”, b “1011” 输出&#xff1a;“10101” …

网络如何发送一个数据包

网络如何发送一个数据包 网络消息发送就是点一点屏幕。 骚瑞&#xff0c;这一点都不好笑。&#xff08;小品就是我的本质惹&#xff09; 之前我就是会被这个问题搞的不安宁。是怎么知道对方的IP地址的呢&#xff1f;怎么知道对方的MAC呢&#xff1f;世界上计算机有那么多&…

SQL每日一练-0816

今日SQL题&#xff1a;计算每个项目的年度收入增长率 难度系数&#xff1a;&#x1f31f;☆☆☆☆☆☆☆☆☆ 1、题目要求 计算每个项目每年的收入总额&#xff0c;并计算项目收入环比增长率。找出每年收入增长率最高的项目。输出结果显示年份、项目ID、项目名称、项…

【走迷宫】

题目 DFS代码 #include<bits/stdc.h> using namespace std; const int N 110; int matrix[N][N]; int n, m; int dx[4] {-1, 0, 1, 0}, dy[4] {0, 1, 0, -1}; int dis[N][N]; void dfs(int x, int y, int cnt) {if(cnt > dis[n-1][m-1]) return;if(x n-1 &&a…

[AHK V2] 转换乱码“涓浗”为“中国”

想还原乱码字符串:涓浗 用乱码恢复工具 乱码恢复 可以查看到,该乱码的现在编码是gbk,原来编码是utf8 (也就是说原来是UTF-8编码的字符串,用GBK编码解析导致产生乱码,那么解析思路就是将GBK编码还原成UTF-8即可 ) 编码标识可以在这查阅 代码页标识符 GBK就是cp936 U…

基于UE5和ROS2的激光雷达+深度RGBD相机小车的仿真指南(一)---UnrealCV获取深度+分割图像

前言 本系列教程旨在使用UE5配置一个具备激光雷达深度摄像机的仿真小车&#xff0c;并使用通过跨平台的方式进行ROS2和UE5仿真的通讯&#xff0c;达到小车自主导航的目的。本教程使用的环境&#xff1a; ubuntu 22.04 ros2 humblewindows11 UE5.4.3python8 本系列教程将涉及以…

解决旧版CMS内容管理无法登录的问题

最近遇到了输入正确的账户密码&#xff0c;旧版的CMS内容管理的平台提示登录成功却无法跳转的问题 遇到这种情况请不要慌&#xff01;&#xff01;&#xff01; 请按照下面的步骤解决问题&#xff1a; 1.点击账号管理 2.点击右上角的返回旧版控制台 3.点击cloud1环境 4.点击扩…

leetcode13. 罗马数字转整数,流程图带你遍历所有情况

leetcode13. 罗马数字转整数 示例 1: 输入: s “III” 输出: 3 示例 2: 输入: s “IV” 输出: 4 示例 3: 输入: s “IX” 输出: 9 示例 4: 输入: s “LVIII” 输出: 58 解释: L 50, V 5, III 3. 示例 5: 输入: s “MCMXCIV” 输出: 1994 解释: M 1000, CM 900, XC…

RK3588J正式发布Ubuntu桌面系统,丝滑又便捷!

本文主要介绍瑞芯微RK3588J的Ubuntu系统桌面演示&#xff0c;开发环境如下&#xff1a; U-Boot&#xff1a;U-Boot-2017.09 Kernel&#xff1a;Linux-5.10.160 Ubuntu&#xff1a;Ubuntu20.04.6 LinuxSDK&#xff1a; rk3588-linux5.10-sdk-[版本号] &#xff08;基于rk3…

Kubectl 常用命令汇总大全

kubectl 是 Kubernetes 自带的客户端&#xff0c;可以用它来直接操作 Kubernetes 集群。 从用户角度来说&#xff0c;kubectl 就是控制 Kubernetes 的驾驶舱&#xff0c;它允许你执行所有可能的 Kubernetes 操作&#xff1b;从技术角度来看&#xff0c;kubectl 就是 Kubernetes…

力扣面试经典算法150题:找出字符串中第一个匹配项的下标

找出字符串中第一个匹配项的下标 今天的题目是力扣面试经典150题中的数组的简单题: 找出字符串中第一个匹配项的下标 题目链接&#xff1a;https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/description/?envTypestudy-plan-v2&envIdto…