CompletableFuture-应用

news2024/11/13 9:36:22

在这里插入图片描述
可以看到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

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

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

相关文章

数据结构与算法--交换排序与归并排序

文章目录 回顾提要冒泡排序冒泡排序的过程冒泡排序的实现冒泡排序算法评价 快速排序快速排序的划分方法快速排序的过程快速排序的实现快速排序算法性能分析快速排序的改进 归并排序二路归并排序合并两个有序表归并排序示例归并排序算法性能分析 各种内排序方法的比较各种内排序…

SOCKS5代理UDP转发:探秘网络世界的隐形传送带

在这个信息爆炸的时代&#xff0c;网络已经成为我们生活中不可或缺的一部分。然而&#xff0c;网络世界中也充满了各种问题和挑战&#xff0c;比如隐私保护、数据传输的安全性等。今天&#xff0c;我们就来聊聊一种神奇的网络工具——SOCKS5代理&#xff0c;特别是它在UDP转发中…

在撰写跨学科论文时,如何平衡不同研究领域的篇幅和深度?

在学术界&#xff0c;跨学科研究因其能够综合不同领域的知识和方法而受到重视。然而&#xff0c;如何在一篇论文中平衡不同学科的篇幅和深度&#xff0c;是一个常见的挑战。本文将探讨一些有效的策略&#xff0c;帮助你在撰写跨学科论文时&#xff0c;既能展现每个领域的深度&a…

数字产业生态圈如何推动产业加速升级?

在数字化浪潮的推动下&#xff0c;数字产业生态圈逐渐成为产业升级的重要载体。它不仅汇聚了技术创新的源头活水&#xff0c;更通过以下几大途径&#xff0c;为产业注入强劲动力&#xff1a; 1、资源整合&#xff1a;数字产业生态圈将政府、企业、科研机构和高校等多方资源整合…

一个案例讲清5Why分析法,分分钟Get!

探究问题深处的“ 5 why究竟法”&#xff0c;这可不是普通的连连问&#xff0c;而是由丰田创始人丰田佐吉精心锻造的问题挖掘秘籍。简而言之&#xff0c;就是当你遇到一个谜题&#xff0c;连环出击五个“为啥呢&#xff1f;”&#xff0c;一步步揭秘真相的核心。想象一下&#…

C++策略模式Strategy

组件协作– —策略模式strategy &#xff08;运行时可以切换&#xff0c; 运行时多态调用&#xff0c; 不同于if else&#xff0c;&#xff08;bad smell、还占用缓存&#xff09; 只要有if else就应该要想strategy重构 但是如果if else绝对不变的情况&#xff0c;也可以用 原本…

Opencv学习-直方图比较

由于图像的直方图表示图像像素灰度值的统计特性&#xff0c;因此可以通过两幅图像的直方图特性比较 两幅图像的相似程度。从一定程度上来讲&#xff0c;虽然两幅图像的直方图分布相似不代表两幅图像相似&#xff0c;但是两幅图像相似则两幅图像的直方图分布一定相似。例如&…

Openlayer - vue中加载天地图(入门篇)

在vue中安装openlayers npm i --save ol这里说的vue是基于脚手架构建的。 新建个页面&#xff0c;也就是vue文件&#xff0c;配置好路由。接着 就是可以直接放入我的代码运行显示了。 vue利用openlayers加载天地图和高德地图 <template><div class"wrapper&quo…

集团数字化转型方(五)

集团数字化转型方案通过全面整合人工智能&#xff08;AI&#xff09;、大数据分析、云计算和物联网&#xff08;IoT&#xff09;等前沿技术&#xff0c;构建了一个高度智能化的业务平台&#xff0c;从而实现业务流程的自动化、数据驱动的决策支持、精准的市场预测、以及个性化的…

web常见漏洞——XSS

xss 1、xss概述2、环境工具3、反射型xss3.1、利用反射型xss获取cookie 4、DOM型xss4.1、第一关4.2、第二关4.3、第三关4.4、第四关4.5、第五关4.6、第六关4.7、第七关4.8、第八关 5、存储型xss 1、xss概述 XSS全称跨站脚本(Cross Site Scripting)&#xff0c;为避免与层叠样式表…

视频孪生技术在智慧水利(水务)场景中的典型应用展示

一、智慧水利建设规划 根据水利部编制《“十四五”智慧水利建设规划》&#xff0c;建设数字孪生流域、“2N”水利智能业务应用体系、安全可控水利网络安全防护体系、优化健全水利网信保障体系&#xff0c;建成七大江河数字孪生流域&#xff0c;推进水利工程智能化改造&#xf…

C程序设计——常量

前面讲了变量&#xff0c;我们现在讲C语言的常量。 整数、自然数常量 十进制 就好像生活中&#xff0c;如果写一个数字&#xff0c;大家都默认是十进制&#xff0c;在C语言里也一样&#xff0c;比如&#xff1a; int main(void) {int iInt ;iInt 10;printf("%d\r\n&q…

无人机电子调速器详解!!!

电子调速器是无人机动力系统中的关键组件&#xff0c;主要负责将电池提供的直流电转换为交流电&#xff0c;并精确控制电机的转速&#xff0c;从而实现对无人机飞行状态的精确控制。以下是对无人机电子调速器的详细解析&#xff1a; 一、基本功能与原理 功能&#xff1a; 直…

R语言:如何安装包“linkET”

自己在R语言中安装包“linkET”时报错不存在叫‘linket’这个名字的程辑包 尝试了install.packages("linkET")和BiocManager::install("linkET")两种安装办法都不行 >install.packages("linkET") WARNING: Rtools is required to build R pa…

挑选知识库管理软件?9大推荐让你不再纠结

这篇文章介绍了以下工具&#xff1a;PingCode、Worktile、幕布、腾讯文档、坚果云、Notion中国版、Evernote、SharePoint、Confluence。 在选择知识库管理软件时&#xff0c;面对众多选项是否感到头疼&#xff1f;对于部门内部的协作和知识管理&#xff0c;选择一款适合的工具至…

unity json 处理

1. c#对象 -> json public class Item {public int id;public int num;public Item(int id, int num){this.id id;this.num num;} } public class PlayerInfo {public string name;public int atk;public int def;public float moveSpeed;public double roundSpeed;publi…

域名注册查询方法

域名不仅是网站的地址标识&#xff0c;更是企业和个人在互联网上的身份证明。要确保自己的在线品牌安全&#xff0c;了解域名注册查询方法至关重要。本文将介绍几种常见的域名查询方式&#xff0c;帮助您轻松了解网络资产的归属。 1. WHOIS查询&#xff1a; WHOIS&#xff08;…

一站式数仓解决方案:ECharts+Luckysheet+DataX+Doris打造全能式数据中台

数据中台这个词出现的概率非常高&#xff0c;对于一个企业来讲&#xff0c;那么数据中台是什么呢&#xff1f;数据中台就是把数据从各个系统 用数据库对接、API对接、或者文件上传的形式把数据收集起来&#xff0c;整合加工&#xff0c;最后生成分析的结果&#xff0c;这个结果…

上周稼先社区的活动

参天是什么&#xff1f; 最近”参天”很火&#xff0c;不仅MySQL社区&#xff0c;听说Monty最近也跟他们搞了很多活动。其实说起华为的数据库&#xff0c;只有从事数据库行业的人才知道高斯&#xff0c;其他很多人不知道。但是即使从事数据库相关的人&#xff0c;对另外一个产…

C语言04--数组超详解

1.基本概念 逻辑&#xff1a;一次性定义多个相同类型的变量&#xff0c;并存储到一片连续的内存中语法&#xff1a; 数据类型 数组名字 [ 数据的量 ] ; 示例&#xff1a; int a[5]; int Num ; 语法释义&#xff1a; a 是数组名&#xff0c;即这片连续内存的名称[5] …