我最近开始阅读很多关于Node JS的内容,而且从差异化的角度来看,我无法清楚地理解的一件事是异步Vs同步调用如何处理I/O之间的真正区别.
据我所知,在多线程同步环境中,如果启动I/O,则运行的线程被抢占并返回到等待状态.因此,这与NodeJS异步I/O调用的情况基本相同.在Node JS中,当调用I/O时,I/O操作被移出当前运行的线程并被发送到事件解复用器以完成和通知.I/O完成后,回调方法将被推送到事件队列以进行进一步处理.
因此,我看到的唯一区别是在Node JS中我们正在节省内存(由于每个线程拥有多个调用堆栈)和CPU(由于没有上下文切换而保存).如果我只是考虑到我有足够的内存可以购买,那么由于上下文切换而节省CPU是否会带来巨大的性能差异?
如果我的上述理解不正确,那么I/O处理在java线程和节点JS之间如何处理以保持CPU忙并且不浪费CPU周期.我们只保存使用Node JS的上下文切换CPU周期或者存在更多的是?
根据回复,我想补充一个场景:
请求A,请求B同时到达J2ee服务器.在这个多线程环境中,每个请求需要10 ms才能完成.在10 ms内,5 ms用于执行代码逻辑以计算某些逻辑,在I/O中花费5 ms用于从DBMS中提取大型数据集.对DBMS的调用是代码的最后一行,之后响应应该发送到客户端.
如果将同一个应用程序转换为节点JS应用程序,则可能会发生这种情况
请求A来,5毫秒用于处理请求.
DBMS调用是从代码中命中的,但它是非阻塞的.因此将回调方法推送到事件队列.
现在在这种情况下节省的时间在哪里?除了上下文切换和创建2个线程.无论如何,使用Node JS,Req A和Req B都花了10毫秒.?
在阅读 Node JS 时,定义表明 I/O 模型是事件驱动的。这与多线程环境中的中断有何不同?在多线程环境中,当 I/O 操作完成时,会生成中断,等待线程现在会进入读取运行状态。在 Node Js 中,根据 I/O 完成后抛出的事件,将回调处理程序推送到事件队列。
为什么两者不同?