我最近开始阅读很多与Node JS相关的内容,有一件事情从分化的角度来看我还没有能够清楚地理解,那就是异步调用和同步调用在I/O处理方面的真正区别。
据我所知,在一个多线程的同步环境中,如果启动了I/O操作,运行的线程将被抢占,并回到等待状态。因此,这与NodeJS异步I/O调用所发生的情况实质上是相同的。在NodeJS中,当调用I/O时,I/O操作会移出当前正在运行的线程并发送到事件去重复器进行完成和通知。一旦I/O完成,回调方法将被推送到事件队列进行进一步处理。
因此,我唯一看到的区别就是在NodeJS中我们正在节省内存(由于每个线程拥有多个调用堆栈),并且CPU也在节省(因为没有上下文切换)。如果我只考虑我有足够的内存购买,那么仅仅因为上下文切换而节省CPU的性能差异是否如此之大呢?
如果我的理解不正确,那么在处理I/O方面,Java线程与NodeJS在保持CPU繁忙和不浪费CPU周期方面有何不同?我们只是通过NodeJS节省了上下文切换的CPU周期,还是还有更多?
基于回应,我想添加另一种情况:
请求A和请求B同时到达J2ee服务器。在这个多线程环境中,每个请求需要10毫秒才能完成。在10毫秒内,5毫秒用于执行代码逻辑以计算一些逻辑,5毫秒用于I/O,从DBMS中拉取大型数据集。DBMS的调用是代码的最后一行,在此之后,响应应该发送到客户端。
如果将同一应用程序转换为Node JS应用程序,则可能会发生以下情况:
1.请求A到来,使用5 ms处理请求。 2.DBMS调用被击中,但它是非阻塞的。因此,回调方法被推送到事件队列。 3.经过5毫秒,服务请求B并再次将请求B推送到事件队列以完成I/O请求。处理需要花费5毫秒时间。
事件循环运行,接收请求A的回调函数处理程序,然后将响应发送给客户端。因此,在同步代码块处理中,请求A和请求B都需要花费5毫秒,所以响应在10毫秒后发送。
据我所知,在一个多线程的同步环境中,如果启动了I/O操作,运行的线程将被抢占,并回到等待状态。因此,这与NodeJS异步I/O调用所发生的情况实质上是相同的。在NodeJS中,当调用I/O时,I/O操作会移出当前正在运行的线程并发送到事件去重复器进行完成和通知。一旦I/O完成,回调方法将被推送到事件队列进行进一步处理。
因此,我唯一看到的区别就是在NodeJS中我们正在节省内存(由于每个线程拥有多个调用堆栈),并且CPU也在节省(因为没有上下文切换)。如果我只考虑我有足够的内存购买,那么仅仅因为上下文切换而节省CPU的性能差异是否如此之大呢?
如果我的理解不正确,那么在处理I/O方面,Java线程与NodeJS在保持CPU繁忙和不浪费CPU周期方面有何不同?我们只是通过NodeJS节省了上下文切换的CPU周期,还是还有更多?
基于回应,我想添加另一种情况:
请求A和请求B同时到达J2ee服务器。在这个多线程环境中,每个请求需要10毫秒才能完成。在10毫秒内,5毫秒用于执行代码逻辑以计算一些逻辑,5毫秒用于I/O,从DBMS中拉取大型数据集。DBMS的调用是代码的最后一行,在此之后,响应应该发送到客户端。
如果将同一应用程序转换为Node JS应用程序,则可能会发生以下情况:
1.请求A到来,使用5 ms处理请求。 2.DBMS调用被击中,但它是非阻塞的。因此,回调方法被推送到事件队列。 3.经过5毫秒,服务请求B并再次将请求B推送到事件队列以完成I/O请求。
那么在这种情况下节省的时间在哪里?除了上下文切换和创建2个线程外,使用Node JS时Req A和Req B都需要花费10毫秒的时间。?