我最近开始阅读很多关于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 ms用于处理请求。
DBMS调用是从代码中命中的,但它是非阻塞的。所以是一个回调方法 被推送到事件队列。
现在在这种情况下节省的时间是什么?除了上下文切换和创建2个线程。 Req A&无论如何,使用Node JS,Req B都花了10毫秒。 ?
答案 0 :(得分:5)
据我了解,在多线程同步环境中,如果是I / O. 启动后,正在运行的线程被抢占并返回到 等待状态。所以基本上这与NodeJS的情况相同 异步I / O调用。
不,在NodeJS中,异步I / O调用是non-blocking I/O。这意味着一旦线程进行了I / O调用,它就不会等待I / O完成并继续执行下一个语句/任务。
I / O完成后,它从event-loop-queue获取下一个任务,并最终执行在进行I / O调用时给它的回调处理程序。
如果我只是考虑到我有足够的记忆力来购买,那么节省了 仅由于上下文切换而产生的CPU正在带来巨大的性能 差?
除此之外,储蓄也来自这两件事
除了上下文切换和创建2个线程。 Req A&要求B. 无论如何,Node JS都花了10毫秒。 ?
你在这里打折一件事 - 线程在特定间隔后一个接一个地得到两个请求。因此,如果一个线程需要10秒钟,那么将需要一个新线程来执行第二个请求。将此问题分发给成千上万的请求,您的操作系统必须制作数千个线程来处理这么多并发用户。请参阅此analogy。