gpt4 book ai didi

java - 线程池中的代码运行速度比非线程慢得多

转载 作者:行者123 更新时间:2023-12-02 07:47:41 26 4
gpt4 key购买 nike

我有读取一组二进制文件的代码,这些文件本质上由许多序列化的java对象组成。我试图通过运行线程池中文件的读取来并行化代码(Executors.newFixedThreadPool)

我看到的是,当线程化时,读取运行速度实际上比单线程慢 - 慢 1.5 到 10 倍,具体取决于线程数量。

在我的测试用例中,我实际上是从多个线程读取相同文件(35mb),因此我不会以任何方式受到 I/O 的约束。我运行的线程数并不多于 CPU,而且池之间没有任何同步——也就是说,我只是独立处理一堆文件。

有谁知道线程化时性能缓慢的可能原因是什么?我应该寻找什么?或者剖析问题的最佳方法是什么?我已经在类中寻找静态变量,这些变量可以在线程之间共享,但我没有看到任何变量。在线程中实例化时,java.* 类之一的运行速度是否会明显变慢(例如我正在使用的 java.zip.deflate)?
感谢您的任何提示。

更新:另一个有趣的提示是,当单个线程运行时,执行读取的函数的执行时间在高精度上是恒定的,但是当运行多个线程时,我发现计时有显着变化。

最佳答案

在我看来,当您添加多个线程执行相同的工作时,您希望读取 35mb 的 java.zip.deflate 来运行得更快。不会的。事实上,虽然您可能不受 IO 限制,但您添加的每个线程仍然会产生内核开销——缓冲区复制等。即使您完全从内核缓冲区空间中读取,也会产生 CPU 和处理开销。

也就是说,我很惊讶你的速度慢了 1.5 到 10 倍。如果每个处理线程都在写入输出,那么显然不会被缓存。

但是我怀疑您可能会发生内存争用。如果您正在处理 Java 序列化对象流,则需要观察内存消耗,除非您经常重置它。序列化保留了大量对象引用,因此大型连续流可以生成大量 GC 带宽。

我会使用 jconsole 连接到您的程序并仔细观察内存选项卡。当幸存者和老一代空间填满时,您将看到非线性 CPU 影响。

关于java - 线程池中的代码运行速度比非线程慢得多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10604010/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com