Java8实战-总结47
Java8实战-总结47
- CompletableFuture:组合式异步编程
- 让代码免受阻塞之苦
- 使用定制的执行器
- 对多个异步任务进行流水线操作
CompletableFuture:组合式异步编程
让代码免受阻塞之苦
使用定制的执行器
就这个主题而言,明智的选择似乎是创建一个配有线程池的执行器,线程池中线程的数目取决于你预计你的应用需要处理的负荷,但是该如何选择合适的线程数目呢?
调整线程池的大小
《Java并发编程实战》一书中,Brian Goetz和合著者们为线程池大小
的优化提供了不少中肯的建议。这非常重要,如果线程池中线程的数量过多,最终它们会竞争
稀缺的处理器和内存资源,浪费大量的时间在上下文切换上。反之,如果线程的数目过少,正
如你的应用所面临的情况,处理器的一些核可能就无法充分利用。Brian Goetz建议,线程池大
小与处理器的利用率之比可以使用下面的公式进行估算:
Nthreads = NCPU * UCPU * (1 + W/C)
其中:
❑NCPU是处理器的核的数目,可以通过Runtime.getRuntime().availableProcessors()得到
❑UCPU是期望的CPU利用率(该值应该介于0和1之间)
❑W/C是等待时间与计算时间的比率
你的应用99%的时间都在等待商店的响应,所以估算出的W/C比率为100。这意味着如果你期望的CPU利用率是100%,你需要创建一个拥有400个线程的线程池。实际操作中,如果你创建的线程数比商店的数目更多,反而是一种浪费,因为这样做之后,你线程池中的有些线程根本没有机会被使用。出于这种考虑,我们建议你将执行器使用的线程数,与你需要查询的商店数目设定为同一个值,这样每个商店都应该对应一个服务线程。不过,为了避免发生由于商店的数目过多导致服务器超负荷而崩溃,你还是需要设置一个上限,比如100个线程。代码清单如下所示(为“最优价格查询器”应用定制的执行器):
private final Executor executor = Executors.newFixedThreadPool(Math.min(shops.size(), 100), //创建一个线程池,线程池中线程的数目为100和商店数目二者中较小的一个值new ThreadFactory() { public Thread newThread(Runnable r) { Thread t = new Thread(r); t.setDaemon(true); //使用守护线程——这种方式不会阻止程序的关停return t; }
});
注意,你现在正创建的是一个由守护线程构成的线程池。Java程序无法终止或者退出一个正在运行中的线程,所以最后剩下的那个线程会由于一直等待无法发生的事件而引发问题。与此相反,如果将线程标记为守护进程,意味着程序退出时它也会被回收。这二者之间没有性能上的差异。现在,你可以将执行器作为第二个参数传递给supplyAsync工厂方法了。比如,你现在可以按照下面的方式创建一个可查询指定商品价格的CompletableFuture对象:
CompletableFuture.supplyAsync(() -> shop.getName() + " price is " + shop.getPrice(product), executor);
改进之后,使用CompletableFuture方案的程序处理5个商店仅耗时1021秒,处理9个商店时耗时1022秒。一般而言,这种状态会一直持续,直到商店的数目达到我们之前计算的阈值400。这个例子证明了要创建更适合你的应用特性的执行器,利用CompletableFutures向其提交任务执行是个不错的主意。处理需大量使用异步操作的情况时,这几乎是最有效的策略。
并行——使用流还是CompletableFutures?目前为止,你已经知道对集合进行并行计算有两种方式:要么将其转化为并行流,利用map这样的操作开展工作,要么枚举出集合中的每一个元素,创建新的线程,在CompletableFuture内对其进行操作。后者提供了更多的灵活性,你可以调整线程池的大小,而这能帮助你确保整体的计算不会因为线程都在等待I/O而发生阻塞。我们对使用这些API的建议如下。
❑如果你进行的是计算密集型的操作,并且没有I/O,那么推荐使用Stream接口,因为实
现简单,同时效率也可能是最高的(如果所有的线程都是计算密集型的,那就没有必要
创建比处理器核数更多的线程)。
❑反之,如果你并行的工作单元还涉及等待I/O的操作(包括网络连接等待),那么使用
CompletableFuture灵活性更好,你可以像前文讨论的那样,依据等待/计算,或者
W/C的比率设定需要使用的线程数。这种情况不使用并行流的另一个原因是,处理流的
流水线中如果发生I/O等待,流的延迟特性会让我们很难判断到底什么时候触发了等待。
现在已经了解了如何利用CompletableFuture为你的用户提供异步API,以及如何将一个同步又缓慢的服务转换为异步的服务。不过到目前为止,每个Future中进行的都是单次的操作。
对多个异步任务进行流水线操作
让我们假设所有的商店都同意使用一个集中式的折扣服务。该折扣服务提供了五个不同的折扣代码,每个折扣代码对应不同的折扣率。你使用一个枚举型变量Discount.Code来实现这一想法,具体代码如下所示。
public class Discount {public enum Code {NONE(0), SILVER(5), GOLD(10), PLATINUM(15), DIAMOND(20); private final int percentage; Code(int percentage) { this.percentage = percentage; } } // Discount类的具体实现这里暂且不表示
}
还假设所有的商店都同意修改getPrice方法的返回格式。getPrice现在以ShopName:price:DiscountCode的格式返回一个String类型的值。示例实现中会返回一个随机生成的Discount.Code,以及已经计算得出的随机价格:
public String getPrice(String product) {double price = calculatePrice(product); Discount.Code code = Discount.Code.values()[ random.nextInt(Discount.Code.values().length)]; return String.format("%s:%.2f:%s", name, price, code);
}
private double calculatePrice(String product) { delay(); return random.nextDouble() * product.charAt(0) + product.charAt(1);
}
调用getPrice方法可能会返回像下面这样一个String值:
BestPrice:123.26:GOLD
相关文章:
Java8实战-总结47
Java8实战-总结47 CompletableFuture:组合式异步编程让代码免受阻塞之苦使用定制的执行器 对多个异步任务进行流水线操作 CompletableFuture:组合式异步编程 让代码免受阻塞之苦 使用定制的执行器 就这个主题而言,明智的选择似乎是创建一个…...
功能: 在web应用程序中、读取文件
通过使用文件 API,web 内容可以要求用户选择本地文件,然后读取这些文件的内容。这种选择可以通过使用 HTML <input type"file"> 元素或通过拖放来完成。 1.通过 click() 方法使用隐藏的文件 input 元素 你可以隐藏公认难看的文件 <…...
TDD、BDD、ATDD以及SBE的概念和区别
在软件开发或是软件测试中会遇到以下这些词:TDD 、BDD 、ATDD以及SBE,这些词代表什么意思呢? 它们之间有什么关系吗? TDD 、BDD 、ATDD以及SBE的基本概念 TDD:(Test Driven Development)是一种…...
Android studio:打开应用程序闪退的问题
目录 问题描述分析原因解决方法 在开发Android应用程序的过程中遇到的问题 问题描述 在开发(或者叫测试,这么简单的程序可能很难叫开发)好一个android之后,在Android studio中调试开发好的app时,编辑器没有提示错误&a…...
Mysql数据库性能优化--performance_SCHEMA.STATEMENTS语句分析
使用performance_schema解决常见的故障案例 1 检查sql语句 使用performance_schema很容易找到引起性能问题的查询以及原因。 要启动语句检测,需要启动statement类型的插装。 插装类: statement/sql sql语句,如select,或者create table。s…...
[C/C++]数据结构 链表OJ题: 反转链表
描述: 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表 示例: 方法一: 让链表指向反向 如图所示: 代码思路: struct ListNode* reverseList(struct ListNode* head) {struct ListNode* n1NULL;struct ListNode* n2head;struct ListNode*…...
深度学习之基于YoloV5交通信号标志识别系统
欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 基于YoloV5交通信号标志识别系统介绍 基于YoloV5的交通信号标志识别系统是一种深度学习应用,旨在通过使…...
Linux命令大全
荒诞也好,愚笨也好,总会过去的 文章目录 文件相关压缩相关tarzip 进程相关pskill 网络相关netstat IPC相关ipcsipcrm 系统资源相关topfreefdiskdfdu 权限相关umaskchmodchownchgrp 总结 文件相关 ls:列出当前目录中的文件和子目录。 ls常用…...
元宇宙是否为噱头?若不是,什么是元宇宙?他的概念、技术、应用和影响是什么?
文章来源:元宇宙的概念、技术、应用与影响——一项系统性文献综述 - 中国知网 (cnki.net) 摘要 [目的/意义]系统综述与分析当前国内外的元宇宙研究现状,有利于准确把握元宇宙发展方向,强化元宇宙基础研究,争取元宇宙建构权。[方法…...
293_C++_告警类
2、IncPos S32 AlarmList::IncPos(U32 *pu32Pos, U32 *pu32Cycle) {if((pu32Pos == NULL) || (pu32Cycle == NULL))</...
MySQL基础操作
注:mysql是大小写不敏感的. 1.数据库基础操作(展示) //1.展示当前数据库 show databases;//2.创建数据库 create database 数据库名;//3.使用数据库 use 数据库名;//4.删除数据库 drop database 数据库名;2.SQL中基本类型 2.1 数值类型(整数和浮点型) 注:decimal和numeric…...
ajax样式演示
以下是一段Ajax的演示代码,实现了通过Ajax获取后台数据并将其显示到前台页面上。 HTML文件: <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>Ajax演示</title></head><body><h1>学生…...
Web前端—CSS高级(定位、高级技巧、CSS修饰属性、综合案例:购物网站轮播图)
版本说明 当前版本号[20231108]。 版本修改说明20231107初版20231108对知识点(圆点)进行补充 目录 文章目录 版本说明目录day08-CSS高级01-定位相对定位绝对定位定位居中固定定位堆叠层级 z-index定位总结 02-高级技巧CSS精灵案例-京东服务HTML结构CS…...
linux的sftp复制传输文件
连接远程服务器 sftp -P 端口号 用户名主机 例如:sftp -P 80 ubuntu172.168.0.1 并按照提示输入密码 分别使用命令查看本地当前路径(Local) 和远程路径(Remote) pwd lpwd 使用 cd 远程路径和 lcd 本地路径分别进入对…...
【星海出品】flask(一)demo
如何安装很早就讲过了,这里就省略了 创建虚拟环境 python -m venv ./venv 激活虚拟环境 source venv/Scripts/activate 退出虚拟环境 deactivate 打开一个vue项目,安装一些东西,然后启动 npm run serve npm install element-plus --save npm…...
从vue源码中看diff算法
一、v-for必须要指定key,其作用是什么? 在源码中有一个函数为,其中就是通过判断两个vnode的type和key进行判断,如果这两个属性相同,那么这两个vnode就是相同,所以在设置key的时候也不可以设置为object等无…...
【17】c++11新特性 —>弱引用智能指针weak_ptr(2)
返回管理this的shared_ptr 通过wek_ptr返回管理this资源的共享智能指针对象shared_ptr。C11中为我们提供了一个模板类叫做std::enable_shared_from_this,这个类中有一个方法叫做shared_from_this(),通过这个方法可以返回一个共享智能指针,在…...
如何去除视频水印?三种简便有效的方法解决视频水印问题
在当今社交媒体时代,视频分享已成为一种流行趋势。然而,很多人在分享自己的作品时却苦于视频上存在的水印,水印通常是出于版权保护或品牌推广的目的而添加到视频中的,但有时它们可能会对用户体验造成负面影响。 如果您正在寻找如何…...
快速构建高质量中文APP登录注册页面Figma源文件
在这个数字化时代,移动应用程序(APP)已经成为我们日常生活中不可或缺的一部分。如果您正在为您的中文APP开发登录注册页面,并寻找高质量的UI设计素材,那么您来对地方了!我们为您提供了一个完整的Figma源文件…...
MySQL库的库操作指南
1.创建数据库 一般格式:create database (if not exists) database1_name,database2_name...... 特殊形式: create database charset harset_name collate collate_name 解释: 红色字是用户自己设置的名称charset:指定数据…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...
