Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 多线程客户端网络应用程序的性能_Java_Multithreading_Performance_Network Programming - Fatal编程技术网

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

Java 多线程客户端网络应用程序的性能,java,multithreading,performance,network-programming,Java,Multithreading,Performance,Network Programming,我已经实现了一个向服务器发送请求的客户端应用程序。它的工作方式可以非常简单地描述。我指定了一些线程。每个线程都会重复向服务器发送请求并等待响应。 我已经为不同数量的线程绘制了客户端的总吞吐量。虚拟客户机的数量并不重要,我感兴趣的是图右侧的最大饱和性能 我很惊讶,因为我没想到性能会随着线程数的增加而增加。事实上,处理器的大部分时间都花在阻塞Java中的i/o(阻塞套接字),因为客户机-服务器通信有1ms的延迟,并且客户机在8核机器上运行 我在网上寻找解决方案,这个答案似乎意味着阻塞I/o的等待时

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

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

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

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

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

我在网上寻找解决方案,Quora上的这个答案似乎 意味着阻塞i/o的等待时间可以安排为使用 其他任务。是真的,特别是对于Java阻塞套接字

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

在这种情况下,为什么我不能得到线性缩放的数量 线程

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

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

将其与正在执行任务的线程进行对比。上下文切换占用相同的时间。但是,当允许运行CPU限制的任务时,它会在很长一段时间内利用CPU,从而使上下文切换相对便宜。这会提高CPU的总体利用率


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

使用每连接一个线程的模型不能很好地扩展,因为它会在所有情况下创建大堆栈,CPU上的上下文切换可能会开始导致大延迟。您可以使用具有非阻塞IO的单个线程进行所有等待,这些等待应该能够处理10个数千个连接。我不太愿意推荐一篇具体的文章,但如果你需要的话,我会推荐的。它之所以平衡,是因为切换的数量以及在每次切换过程中所能做的工作是多么少。我现在意识到,在我的情况下,阻塞I/o并不是最佳选择。我没想到上下文切换会造成这样的开销,我的计划是增加线程的数量。但是,这是大学课程的一部分,了解性能是最重要的,因此我现在不会更改实施。这个建议将对下次有所帮助。谢谢。我想每个线程都使用自己的连接,在服务器端,每个连接都由专用线程提供服务。因此,客户机线程的数量越多,服务器线程的数量就越多,因此吞吐量也会增加。@AlexeiKaigorodov相当多的服务器实现不使用每个连接一个线程的模型,因为当连接达到1000个时,它很快就会崩溃。也许在这种情况下,这是两个连接上的每个线程,但正如其他人所说,使用非阻塞i/o并在单个线程中完成所有操作可能会更有效。@AndrewTFinnell服务器是否使用每个连接的线程模型或使用非阻塞i/o异步处理请求并不重要。在这两种情况下,请求是并行处理的,这是客户端可以看到的。这非常有用。作为对上下文切换假设的理性检验,您是否知道上下文切换延迟的数量级?为了让它在这里产生不同,我假设它必须至少是0.1毫秒。另外,如果您能给我指出任何监测工具来证明这种影响,我将非常感激。这里的答案将表明0.01毫秒或多或少是一个数量级。这似乎是合理的。这个数字在很大程度上取决于硬件和缓存中线程的工作集: