从java角度对比nodejs、fastapi,同步和异步区别

 我之前一直用java语言编程,最近一年用python fastapi和nodejs nestjs开发了一些项目,站在java程序员的角度谈谈异步编程和同步编程的区别,主要在两方面

  1. 处理请求,java常用的tomcat是多线程处理请求并执行代码,同步阻塞型。而nodejs是单线程处理请求并执行代码,异步非阻塞。
  2. 编程思想,同步利用多线程完成非阻塞目的,写代码按顺序写。而异步天生能完成非阻塞,比同步多了回调、async await等,写代码也不是顺序、没那么容易理解。

参考这两章节重要

Node.js 中文网 — Node.js 事件循环

Node.js 中文网 — 不要阻塞事件循环(或工作池)

一。同步编程

习惯了java开发,会觉得同步编程易于理解,符合常见顺序思维。

同步tomcat如何处理请求

我们知道tomcat默认用150个线程,每个线程处理一个客户端请求,堆积的客户端请求会进入队列。某个客户端处理请求的线程被io或大量计算堵塞,不影响tomcat的剩余149处理请求,所以tomcat依然能处理其他客户端的请求。

同步编程该如何完成非阻塞需求

在主线程执行期间,如果想同时执行另一个任务,就新建线程去做,并通过callable get方法、线程阀、中断等办法得知线程执行结果。

以下面代码为例,我们想让第二件IO事和第三件IO事同时进行、不想主线程被第二件IO事堵塞住,所以用新线程执行第二件IO事,但想获得第二件事结果要在主线程堵塞等待get。注意在编程中,第二件事应该是阻塞型代码比如IO、长时间计算型任务利用空闲的cpu执行,否则新建线程无意义。

        System.out.println("第一件事");FutureTask futureTask = new FutureTask<>((Callable) () -> {System.out.println("第二件事IO");return 1;});Thread thread = new Thread(futureTask);thread.start();System.out.println("第三件事IO");Object o = futureTask.get();System.out.println("第二三件事IO都完成了,第二件事结果"+o);

二。异步编程

nodejs

nodejs的思想是用较少的线程处理更多的客户端请求。

nodejs如何处理请求和io

nodejs有两种线程,事件循环线程和工作池线程,事件循环线程是单线程,工作池线程有多个。

事件循环线程用来干嘛?看看官网文档,如下Node.js 中文网 — 不要阻塞事件循环(或工作池)

我认为nodejs中文网翻译的不对,估计是工具翻译的,还是自己看英文。

第一段话我反复看了好几次 1.nodejs初始化模块和注册事件回调,然后执行事件循环,nodejs通过回调的方式响应处理客户端请求,这个处理客户端请求的回调是以同步方式执行的,并且可能注册异步请求继续处理。(这段话意思是事件循环线程用来处理客户端请求,处理方式是注册事件和回调,在处理客户端请求回调的过程中,它可能注册新的异步事件,我这里翻译为事件,但原文用的是may register asynchronous requests ,requests不是指客户端http请求、而是异步操作请求。比如平常@get等接口接受请求、并在接口中写新的异步io操作就会注册到事件里)

2.第二段又重复说时事件循环会处理在回调中发起的异步非阻塞请求,比如网络io,我理解是进一步解释了

3.总结,事件循环线程干了两件事  (1)处理事件回调 ,这里包含了处理客户端请求,因为它也是通过回调处理;同时回调中如果注册了新事件,新事件同样由事件循环线程处理 (2)处理非阻塞异步事件如网络IO,为什么要强调网络io呢?看了下面工作线程的作用就明白了,因为文件io是工作线程处理的。

举个例子再理解下,平常写代码@get接口,里面打一行日志、然后查数据库、有查询结果后处理。事件循环线程处理请求,然后用回调执行代码,回调里打一行日志,查数据库是网络io,于是事件循环线程发起了这次网络io,但不等待结果,有结果后回调继续在事件循环中完成。

工作池线程用来干嘛的?当碰到一下api时,会自动使用工作池线程执行

  1. I/O 密集型

    1. DNSdns.lookup()dns.lookupService().

    2. 文件系统:除 fs.FSWatcher() 之外的所有文件系统 API 以及明确同步的 API 都使用 libuv 的线程池。

  2. CPU 密集型

    1. 加密crypto.pbkdf2()crypto.scrypt()crypto.randomBytes()crypto.randomFill()crypto.generateKeyPair().

    2. Zlib:除了明确同步的 zlib API 之外,所有 zlib API 都使用 libuv 的线程池。

到这里就明白了,nodejs用事件循环处理请求,处理请求的回调中有异步操作会注册为新事件、网络io则继续由事件循环线程处理,一旦有文件io或加密等规定api会自动由工作线程处理。

所以nodejs官网一再强调,不要阻塞事件循环,这是开发者干的事。详细阅读文档,它说了哪些操作容易堵塞、如何避免堵塞客户端请求,分区卸载等Node.js 中文网 — 不要阻塞事件循环(或工作池)

nodejs处理事件循环的过程

Node.js 中文网 — Node.js 事件循环

在文档这章里讲各个事件循环的各阶段

nodejs完成非阻塞需求代码

以下代码完成了上面java代码相同的事,第二件事用异步执行,想获取第二件事的结果用await。  这里与tomcat不同的是,执行线程只有1个,await并没有阻塞到计算线程,计算线程可以继续执行其他不阻塞的代码,直到等待事件回调。


async function a(){
console.log("第一件事")const promise = b();console.log("第三件事")
const result = await promise;
console.log("第二件事结果"+ result);
}
async function b(){
console.log("第二件事");return 1;
}
a();

关于nodejs执行宏任务微任务 

以上的代码里,先打印第二件事还是第三件事,这与宏任务微任务有关,也不难,可以参考

node【一文搞懂:浏览器和node的事件循环机制】【微任务和宏任务】_node事件循环-CSDN博客

当然用异步不是为了打印日志,这是没意义的,异步是为了io

await怎么实现的 

await是个promise语法糖,await 一个promise,和promise.then()差不多。虽然await看起来像是一种特殊的操作,但本质上它也是基于Promise机制的。

await一个Promise时,实际上是等待这个Promise的状态转换。如果Promise的状态还处于pending,那么与这个Promise最终状态转换相关的回调(例如resolvereject后的回调)就会在微任务队列中处于等待状态。在事件循环中,微任务队列会在宏任务之间被检查和执行。一旦Promise的状态发生改变,微任务队列中的相应回调就会被触发,从而使得await后的代码能够继续执行(如果Promiseresolve)或者抛出异常(如果Promisereject)。

python fastapi

fastapi的异步处理请求过程跟node一样,只是fastapi同时支持异步和同步,当接口方法加了async时,走异步处理流程,当不加async时请求由线程池进行处理、跟tomcat类似!

参考这篇文章python - uvicorn 如何调节线程池大小 - SegmentFault 思否

这篇文章也很好的体现了fastapi异步和同步编程的区别FastAPI到底用不用async?_fastapi async-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《图解设计模式》笔记(五)一致性

十一、Composite模式&#xff1a;容器与内容的一致性 像文件夹与文件一样&#xff0c;文件夹中可以放子文件夹与文件&#xff0c;再比如容器中可以放更小的容器和具体内容。 Composite模式&#xff1a;使容器与内容具有一致性&#xff0c;创造出递归结构。 Composite&#x…

爬虫学习笔记之Robots协议相关整理

定义 Robots协议也称作爬虫协议、机器人协议&#xff0c;全名为网络爬虫排除标准&#xff0c;用来告诉爬虫和搜索引擎哪些页面可以爬取、哪些不可以。它通常是一个叫做robots.txt的文本文件&#xff0c;一般放在网站的根目录下。 robots.txt文件的样例 对有所爬虫均生效&#…

电脑可以自己换显卡吗?怎么操作

电脑是否可以自己换显卡主要取决于电脑的类型&#xff08;台式机或笔记本&#xff09;以及电脑的硬件配置。以下是对这一问题的详细解答及操作步骤&#xff1a; 一、判断电脑是否支持更换显卡 台式机&#xff1a;大多数台式电脑都支持更换显卡。只要主板上有PCIe插槽&#xff…

【玩转 Postman 接口测试与开发2_014】第11章:测试现成的 API 接口(下)——自动化接口测试脚本实战演练 + 测试集合共享

《API Testing and Development with Postman》最新第二版封面 文章目录 3 接口自动化测试实战3.1 测试环境的改造3.2 对列表查询接口的测试3.3 对查询单个实例的测试3.4 对新增接口的测试3.5 对修改接口的测试3.6 对删除接口的测试 4 测试集合的共享操作4.1 分享 Postman 集合…

华为支付-免密支付接入免密代扣说明

免密代扣包括支付并签约以及签约代扣场景。 开发者接入免密支付前需先申请开通签约代扣产品&#xff08;即申请配置免密代扣模板及协议模板ID&#xff09;。 华为支付以模板维度管理每一个代扣扣费服务&#xff0c;主要组成要素如下&#xff1a; 接入免密支付需注意&#x…

Redis - 全局ID生成器 RedisIdWorker

文章目录 Redis - 全局ID生成器 RedisIdWorker一、引言二、实现原理三、代码实现代码说明 四、使用示例示例说明 五、总结 Redis - 全局ID生成器 RedisIdWorker 一、引言 在分布式系统中&#xff0c;生成全局唯一ID是一个常见的需求。传统的自增ID生成方式在分布式环境下容易出…

YOLOv11实时目标检测 | 摄像头视频图片文件检测

在上篇文章中YOLO11环境部署 || 从检测到训练https://blog.csdn.net/2301_79442295/article/details/145414103#comments_36164492&#xff0c;我们详细探讨了YOLO11的部署以及推理训练&#xff0c;但是评论区的观众老爷就说了&#xff1a;“博主博主&#xff0c;你这个只能推理…

用Python获取股票数据并实现未来收盘价的预测

获取数据 先用下面这段代码获取上证指数的历史数据&#xff0c;得到的csv文件数据&#xff0c;为后面训练模型用的 import akshare as ak import pandas as pd# 获取上证指数历史数据 df ak.stock_zh_index_daily(symbol"sh000001")# 将数据保存到本地CSV文件 df.…

RK3576——USB3.2 OTG无法识别到USB设备

问题&#xff1a;使用硬盘接入到OTG接口无热插拔信息&#xff0c;接入DP显示屏无法正常识别到显示设备&#xff0c;但是能通过RKDdevTool工具烧录系统。 问题分析&#xff1a;由于热插拔功能实现是靠HUSB311芯片完成的&#xff0c;因此需要先确保HUSB311芯片驱动正常工作。 1. …

RabbitMQ深度探索:前置知识

消息中间件&#xff1a; 消息中间件基于队列模式实现异步 / 同步传输数据作用&#xff1a;可以实现支撑高并发、异步解耦、流量削峰、降低耦合 传统的 HTTP 请求存在的缺点&#xff1a; HTTP 请求基于响应的模型&#xff0c;在高并发的情况下&#xff0c;客户端发送大量的请求…

maven如何不把依赖的jar打包到同一个jar?

spring boot项目打jar包部署&#xff1a; 经过以下步骤&#xff0c; 最终会形成maven依赖的多个jar&#xff08;包括lib下添加的&#xff09;、 我们编写的程序代码打成一个jar&#xff0c;将程序jar与 依赖jar分开&#xff0c;便于管理&#xff1a; success&#xff1a; 最终…

网络工程师 (21)网络的性能

一、速率&#xff08;数据率或比特率&#xff09; 定义&#xff1a;数据在数字信道上传送的速率&#xff0c;通常以比特每秒&#xff08;bps&#xff09;为单位。常见的速率单位还有千比特每秒&#xff08;kbit/s&#xff09;、兆比特每秒&#xff08;Mbit/s&#xff09;和吉比…

UE5 蓝图学习计划 - Day 14:搭建基础游戏场景

在上一节中&#xff0c;我们 确定了游戏类型&#xff0c;并完成了 项目搭建、角色蓝图的基础设置&#xff08;移动&#xff09;。今天&#xff0c;我们将进一步完善 游戏场景&#xff0c;搭建 地形、墙壁、机关、触发器 等基础元素&#xff0c;并添加角色跳跃功能&#xff0c;为…

计算机毕业设计hadoop+spark+hive民宿推荐系统 酒店推荐系统 民宿价格预测 酒店价预测 机器学习 深度学习 Python爬虫 HDFS集群

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

金蝶云星空k3cloud webapi报“java.lang.Class cannot be cast to java.lang.String”的错误

最近在对接金蝶云星空k3cloud webapi时&#xff0c;报一个莫名其妙的转换异常&#xff0c;具体如下&#xff1a; 同步部门异常! ERP接口登录异常&#xff1a;java.lang.Class cannot be cast to java.lang.String at com.jkwms.k3cloudSyn.service.basics.DeptK3CloudService.…

html的字符实体和颜色表示

在HTML中&#xff0c;颜色可以通过以下几种方式表示&#xff0c;以下是具体的示例&#xff1a; 1. 十六进制颜色代码 十六进制颜色代码以#开头&#xff0c;后面跟随6个字符&#xff0c;每两个字符分别表示红色、绿色和蓝色的强度。例如&#xff1a; • #FF0000&#xff1a;纯红…

老游戏回顾:G2

一个老的RPG游戏。 剧情有独到之处。 ------- 遥远的过去&#xff0c;古拉纳斯将希望之光给予人们&#xff0c;人类令希望之光不断扩大&#xff0c;将繁荣握在手中。 但是&#xff0c;暗之恶魔巴鲁玛将光从人类身上夺走。古拉纳斯为了守护人类与其展开了一场激战&#xff0c…

E4982A,keysight是德科技台式LCR表

是德科技keysightE4982A台式LCR表 是德KEYSIGHT的精密型LCR表E4982A&#xff0c;针对SMD电感器、EMI滤波器等无源元器件的制造测试展现出卓越性能&#xff0c;特别适用于1 MHz至3 GHz高频率范围内的阻抗测试。此外&#xff0c;E4982A还广泛应用于研发领域&#xff0c;凭借其强…

C++, STL容器 array:固定大小数组深度解析

文章目录 引言一、设计哲学与底层实现1.1 零抽象成本的封装1.2 性能特征二、内存优化实践2.1 缓存友好性对比2.2 内存碎片防护三、高级内存管理技巧3.1 精准内存对齐3.2 内存复用模式四、工程实践指南4.1 适用场景4.2 陷阱规避五、未来演进结语引言 在C++标准库中,std::array…

013-51单片机红外遥控器模拟控制空调,自动制冷制热定时开关

主要功能是通过红外遥控器模拟控制空调&#xff0c;可以实现根据环境温度制冷和制热&#xff0c;能够通过遥控器设定温度&#xff0c;可以定时开关空调。 1.硬件介绍 硬件是我自己设计的一个通用的51单片机开发平台&#xff0c;可以根据需要自行焊接模块&#xff0c;这是用立创…