【问题标题】:Multi-Threaded program runs slower than single threaded多线程程序运行速度比单线程慢
【发布时间】:2014-03-25 19:22:26
【问题描述】:

我试图解决Euler Project。要点here。是的,我明白了,没有使用任何算法——我不想这么做。问题是,第二个文件使用 ExecutorService 来查找值 - 我知道结果将不正确,但与单线程文件相比,它正在爬行。我认为创建线程本身可能会将池大小减少到 4 个(我有一个八核处理器),但这没有任何作用。

之前我还使用similar approach 来显着加快使用多线程生成缩略图的速度。但我无法理解是什么导致了这种特殊情况的缓慢。我不是想得到正确的解决方案——我知道我应该先这样做,然后再尝试其他任何事情。我做错了什么。我来这里并不是为了找到问题的解决方案,但我想了解为什么它很慢。我使用了线程访问的static 变量。这可能是个问题吗?

【问题讨论】:

  • 线程运行了多长时间?如果它们是短暂的,那么它可能不值得。他们在 IO 上被阻止了吗?只有在 CPU 受限的情况下才能看到速度提升。
  • 这可能是创建几乎无限数量的 Runnable(包括负数)的开销
  • @Gray 我正在使用ExecutorService,所以希望所有线程都可以存活,直到找到一个数字 - 我在执行 5-6 分钟后终止程序,因为它运行非常缓慢。我应该运行更长的时间吗?但是线程中的调用仅持续 1-2 左右的几毫秒。在 IO 上被阻止 - 现在我只有一行 System.out.println - 告诉我在检查因子中达到的计数仍然重要吗?与单线程相比,它的运行速度仍然慢得多。
  • @immibis 即使在运行了几分钟后,我也看到了计数——不是线程,而是线程执行特定方法的次数——我已经达到了几十万。线程数 - 我正在打印线程 ID,我看到的最大线程 ID 是 15。另外我认为我正在使用线程池,所以它仍然会创建无限线程。我错过了什么吗?

标签: java multithreading performance


【解决方案1】:

我知道结果将不正确,但与单线程相比它正在爬行

我在执行 5-6 分钟后终止程序,因为它运行得很慢

首先,我假设您使用的是Executors.newFixedThreadPool(),它分配固定数量的线程,不是缓存线程池。

在我看来,您可能正在创建大量工作,而您的程序内存不足。当你填满内存时,JVM 在 GC 上的工作越来越努力,这表明你的进程越来越慢。您可以使用 jconsole 连接到应用程序以验证线程数和内存。您还可以对其进行线程转储 (kill -QUIT pid) 并查看您分叉了多少作业。

如果您正在创建大量工作,而您的 ExecutorService 跟不上,那么您将需要限制工作生产。有几种不同的方法可以做到这一点。这是我使用的:

Process Large File for HTTP Calls in Java

结合从那里链接的其他解决方案。

我认为创建线程本身可能会产生开销,将池大小减少到 4(我有一个八核处理器),但这没有任何作用。

是的,这似乎不是处理器问题。我会把它移回 8。如果这真的使盒子无法使用,那么在你的 ExecutorService 中尝试 7 或 6 个线程。

编辑:

在查看了更多代码之后,您正在执行一堆不同步的数据更新,这将导致奇怪的结果。每当您修改共享内存(在您的情况下为共享 static 字段)时,您将不得不在互斥锁 (++) 和内存共享方面进行一些同步。

如果可以的话,我会考虑使用AtomicLong 和其他人,但你应该阅读一些关于共享内存和同步的线程教程:http://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html

【讨论】:

  • 我使用了 Java Visual VM,我发现大多数线程大部分时间都花在监视器(红线)上,高达 99% 的时间——对于它们的静态变量也是如此正在访问和修改并且必须等待它?我没有在任何地方使用过synchronized。 Image1Image2
  • 任何时候你读或写共享内存@ykesh,你都需要做某种同步。我在帖子中添加了 Java 线程教程。
  • 这意味着您的线程可能看不到这些共享变量的最新值。但是不确定这是否是您的性能问题。
  • 是的,在运行超过 15 分钟的长时间后,我得到了一个 java.lang.OutOfMemoryError: GC overhead limit exceeded,因此创建了太多工作。同样从 VisualVM 来看,它大部分时间都花在了 Monitor 上——所以正如你所说,有一些同步。谢谢!
猜你喜欢
  • 2016-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-05
  • 1970-01-01
  • 2014-10-28
相关资源
最近更新 更多