Js和Java的高并发对比

355 阅读3分钟

不得不说这个问题是折磨人的。根据查询的结果,

本文参考的测试结果来自于:文章

疑问

多线程(Java)处理并发的性能会输给单线程(Nodejs)处理并发吗?

如果每个请求到达Java server之后,都要开启一个线程处理req/res,一定会在创建线程上下文和切换线程上下文之间浪费不必要的性能。但是现在都是采用线程池中的线程来运行程序,很大程度避免了创建线程上下文的损耗。

那么为什么Java处理并发的能力弱于Nodejs处理并发的能力?

硬件资源对并发的影响

假设一:硬件资源无限

假设CPU数量,内存都是无限的,OS允许开无限多的线程,程序在利用内存时不加以任何限制。那么无论是Nodejs还是Java的并发都是无限的。

假设二:内存和CPU均是有限的

内存:8G

CPU:8

Nodejs使用Event-Loop中的队列管理客户端发送的socket数据结构,因为Nodejs是单线程处理js的,同一时刻主线程只能处理一个socket,所以会出现大量的socket在队列中排队等待主线程处理的情况。此时队列的容量决定了并发的上限。所有的socket都要等待主线程逐个处理,所以此时如果主线程不能运行过多的js代码才能保证在高并发下的高效率。所以个人认为在保证高并发的情况下Nodejs在后端的最合适的应用场景为:处理少量业务逻辑代码的项目(IM),需要部署微服务的项目(微服务拆解了js的代码量)。

Java使用多线程处理并发,如果每个线程都来自于线程池,而且采用异步非阻塞的方式处理业务逻辑层,那么根据文章使用drill测试得到的结果(Java的高并发能力输给了Nodejs的高并发,而且此时Java和Nodejs采用的是同样的架构实现的server,即多线程异步非阻塞服务器),可以推断Java server的线程上下文切换对性能的损耗 + 处理异步非阻塞代码的性能损耗 > Nodejs server的线程上下文切换对性能的损耗 + 处理异步非阻塞代码的性能损耗。

内存和CPU均是极少的

内存:3M

CPU:2

假设一个线程需要1M内存,10000000的并发量,Java需要同时开max(max为线程池允许开启的线程的上限)个线程同时处理max个请求,所以此时需要max*1M的内存分配给它。而对于node.js,最少只需1M来处理所有的请求,代价就是每个客户端都需要多等一会儿。此时Nodejs并发能力和处理效率均优于Java。

综上所述:在仅具有少量js代码的情况下(不要让主线程阻塞对其他socket的处理),Nodejs在有限的硬件资源下并发能力优于Java。