当前位置: 首页 > news >正文

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&#xff0c;web 内容可以要求用户选择本地文件&#xff0c;然后读取这些文件的内容。这种选择可以通过使用 HTML <input type"file"> 元素或通过拖放来完成。 1.通过 click() 方法使用隐藏的文件 input 元素 你可以隐藏公认难看的文件 <…...

TDD、BDD、ATDD以及SBE的概念和区别

在软件开发或是软件测试中会遇到以下这些词&#xff1a;TDD 、BDD 、ATDD以及SBE&#xff0c;这些词代表什么意思呢&#xff1f; 它们之间有什么关系吗&#xff1f; TDD 、BDD 、ATDD以及SBE的基本概念 TDD&#xff1a;&#xff08;Test Driven Development&#xff09;是一种…...

Android studio:打开应用程序闪退的问题

目录 问题描述分析原因解决方法 在开发Android应用程序的过程中遇到的问题 问题描述 在开发&#xff08;或者叫测试&#xff0c;这么简单的程序可能很难叫开发&#xff09;好一个android之后&#xff0c;在Android studio中调试开发好的app时&#xff0c;编辑器没有提示错误&a…...

Mysql数据库性能优化--performance_SCHEMA.STATEMENTS语句分析

使用performance_schema解决常见的故障案例 1 检查sql语句 使用performance_schema很容易找到引起性能问题的查询以及原因。 要启动语句检测&#xff0c;需要启动statement类型的插装。 插装类&#xff1a; statement/sql sql语句&#xff0c;如select,或者create table。s…...

[C/C++]数据结构 链表OJ题: 反转链表

描述: 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表 示例: 方法一: 让链表指向反向 如图所示: 代码思路: struct ListNode* reverseList(struct ListNode* head) {struct ListNode* n1NULL;struct ListNode* n2head;struct ListNode*…...

深度学习之基于YoloV5交通信号标志识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 基于YoloV5交通信号标志识别系统介绍 基于YoloV5的交通信号标志识别系统是一种深度学习应用&#xff0c;旨在通过使…...

Linux命令大全

荒诞也好&#xff0c;愚笨也好&#xff0c;总会过去的 文章目录 文件相关压缩相关tarzip 进程相关pskill 网络相关netstat IPC相关ipcsipcrm 系统资源相关topfreefdiskdfdu 权限相关umaskchmodchownchgrp 总结 文件相关 ls&#xff1a;列出当前目录中的文件和子目录。 ls常用…...

元宇宙是否为噱头?若不是,什么是元宇宙?他的概念、技术、应用和影响是什么?

文章来源&#xff1a;元宇宙的概念、技术、应用与影响——一项系统性文献综述 - 中国知网 (cnki.net) 摘要 [目的/意义]系统综述与分析当前国内外的元宇宙研究现状&#xff0c;有利于准确把握元宇宙发展方向&#xff0c;强化元宇宙基础研究&#xff0c;争取元宇宙建构权。[方法…...

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的演示代码&#xff0c;实现了通过Ajax获取后台数据并将其显示到前台页面上。 HTML文件: <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>Ajax演示</title></head><body><h1>学生…...

Web前端—CSS高级(定位、高级技巧、CSS修饰属性、综合案例:购物网站轮播图)

版本说明 当前版本号[20231108]。 版本修改说明20231107初版20231108对知识点&#xff08;圆点&#xff09;进行补充 目录 文章目录 版本说明目录day08-CSS高级01-定位相对定位绝对定位定位居中固定定位堆叠层级 z-index定位总结 02-高级技巧CSS精灵案例-京东服务HTML结构CS…...

linux的sftp复制传输文件

连接远程服务器 sftp -P 端口号 用户名主机 例如&#xff1a;sftp -P 80 ubuntu172.168.0.1 并按照提示输入密码 分别使用命令查看本地当前路径&#xff08;Local&#xff09; 和远程路径&#xff08;Remote&#xff09; pwd lpwd 使用 cd 远程路径和 lcd 本地路径分别进入对…...

【星海出品】flask(一)demo

如何安装很早就讲过了&#xff0c;这里就省略了 创建虚拟环境 python -m venv ./venv 激活虚拟环境 source venv/Scripts/activate 退出虚拟环境 deactivate 打开一个vue项目&#xff0c;安装一些东西&#xff0c;然后启动 npm run serve npm install element-plus --save npm…...

从vue源码中看diff算法

一、v-for必须要指定key&#xff0c;其作用是什么&#xff1f; 在源码中有一个函数为&#xff0c;其中就是通过判断两个vnode的type和key进行判断&#xff0c;如果这两个属性相同&#xff0c;那么这两个vnode就是相同&#xff0c;所以在设置key的时候也不可以设置为object等无…...

【17】c++11新特性 —>弱引用智能指针weak_ptr(2)

返回管理this的shared_ptr 通过wek_ptr返回管理this资源的共享智能指针对象shared_ptr。C11中为我们提供了一个模板类叫做std::enable_shared_from_this&#xff0c;这个类中有一个方法叫做shared_from_this()&#xff0c;通过这个方法可以返回一个共享智能指针&#xff0c;在…...

如何去除视频水印?三种简便有效的方法解决视频水印问题

在当今社交媒体时代&#xff0c;视频分享已成为一种流行趋势。然而&#xff0c;很多人在分享自己的作品时却苦于视频上存在的水印&#xff0c;水印通常是出于版权保护或品牌推广的目的而添加到视频中的&#xff0c;但有时它们可能会对用户体验造成负面影响。 如果您正在寻找如何…...

快速构建高质量中文APP登录注册页面Figma源文件

在这个数字化时代&#xff0c;移动应用程序&#xff08;APP&#xff09;已经成为我们日常生活中不可或缺的一部分。如果您正在为您的中文APP开发登录注册页面&#xff0c;并寻找高质量的UI设计素材&#xff0c;那么您来对地方了&#xff01;我们为您提供了一个完整的Figma源文件…...

MySQL库的库操作指南

1.创建数据库 一般格式&#xff1a;create database (if not exists) database1_name,database2_name...... 特殊形式&#xff1a; create database charset harset_name collate collate_name 解释&#xff1a; 红色字是用户自己设置的名称charset&#xff1a;指定数据…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

抽象类和接口(全)

一、抽象类 1.概念&#xff1a;如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象&#xff0c;这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法&#xff0c;包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中&#xff0c;⼀个类如果被 abs…...

DBLP数据库是什么?

DBLP&#xff08;Digital Bibliography & Library Project&#xff09;Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高&#xff0c;数据库文献更新速度很快&#xff0c;很好地反映了国际计算机科学学术研…...

2025年低延迟业务DDoS防护全攻略:高可用架构与实战方案

一、延迟敏感行业面临的DDoS攻击新挑战 2025年&#xff0c;金融交易、实时竞技游戏、工业物联网等低延迟业务成为DDoS攻击的首要目标。攻击呈现三大特征&#xff1a; AI驱动的自适应攻击&#xff1a;攻击流量模拟真实用户行为&#xff0c;差异率低至0.5%&#xff0c;传统规则引…...

qt+vs Generated File下的moc_和ui_文件丢失导致 error LNK2001

qt 5.9.7 vs2013 qt add-in 2.3.2 起因是添加一个新的控件类&#xff0c;直接把源文件拖进VS的项目里&#xff0c;然后VS卡住十秒&#xff0c;然后编译就报一堆 error LNK2001 一看项目的Generated Files下的moc_和ui_文件丢失了一部分&#xff0c;导致编译的时候找不到了。因…...

raid存储技术

1. 存储技术概念 数据存储架构是对数据存储方式、存储设备及相关组件的组织和规划&#xff0c;涵盖存储系统的布局、数据存储策略等&#xff0c;它明确数据如何存储、管理与访问&#xff0c;为数据的安全、高效使用提供支撑。 由计算机中一组存储设备、控制部件和管理信息调度的…...