java - 多线程客户端网络应用程序的性能

标签 java multithreading performance network-programming

我已经实现了一个向服务器发送请求的客户端应用程序。它的工作方式可以非常简单地描述。我指定了多个线程。每个线程都会重复向服务器发送请求并等待答案。 Throughput

我已经绘制了不同数量线程的客户端总吞吐量。虚拟客户端的数量并不重要,我感兴趣的是图表最右侧的最大饱和性能。

我很惊讶,因为我没想到性能会随着线程数量的增加而变化。事实上,大部分处理器时间都花在了 Java 中的阻塞 i/o(阻塞套接字)上,因为客户端与服务器之间的通信有 1 毫秒的延迟,并且客户端运行在 8 核机器上。

我在网上寻找解决方案,这个答案在 Quora似乎意味着阻塞 i/o 的等待时间可以安排用于其他任务。是真的吗,专门针对 Java 阻塞套接字?在这种情况下,为什么我不能随线程数量进行线性缩放?

如果这很重要,我会在云中运行此应用程序。另外,这是一个更大的应用程序的一部分,但我已将该组件确定为整个设置的瓶颈。

最佳答案

I have looked for solutions online, this answer on Quora seems to imply that the waiting time for blocking i/o can be scheduled to use for other tasks. Is is true, specifically for Java blocking sockets ?

常规 Java 线程一对一映射到操作系统级线程。它们是等价的。所以,是的,Java 确实如此,事实上,其他所有语言也是如此。除非它使用 Green Threads或非阻塞 IO。

In that case, why don't I get linear scaling with the number of threads ?

从CPU的角度思考你在做什么。 CPU 执行代价高昂的上下文切换并允许某些线程运行。该线程在很短的时间内使用 CPU 来准备网络调用,然后它会阻塞很长时间(对于工作在 3GHz 的 CPU 来说,毫秒是相当长的)。

因此,在需要另一次上下文切换之前,每个线程只执行一小部分工作。这意味着 CPU 的大量时间都浪费在上下文切换上,而不是做有用的工作。

将其与执行 CPU-bound 的线程进行对比任务。上下文切换需要相同的时间。但是,当允许运行受 CPU 限制的任务时,它会设法长时间利用 CPU,相比之下,上下文切换的成本会更低。这会提高总体 CPU 利用率。

因此,一方面,您会看到每个新线程的速率更高,因为您实际上执行了更多并发 I/O 操作。另一方面,每个新线程都会增加成本。所以每个额外线程的边际效益每次都会小一点。如果您继续添加线程,在某些时候您甚至会达到每个新线程的速率都会下降的程度。

关于java - 多线程客户端网络应用程序的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53601767/

相关文章:

node.js - 将异步代码视为 Node.js 中的线程?

c++ - 高性能计算中的数组C[]=A[]*B[]

c++ - 条件递增,你应该分支吗?

c# - 在 C# 中将二进制数据写入文件的最高效方法

javascript - 我在保存日期和时间时遇到问题?

multithreading - Delphi 7 的线程框架 - 有吗?

java - 在循环语句中声明变量在 Java 中如何工作

c++ - 在各自的线程上运行多个对象似乎多次运行同一个对象

java - 字符串数组的问题

java - 如何从 JSONObject 数据中获取特定字段的内容