Java中的MultiThreading是否需要很长时间才能完成任务?

时间:2010-05-17 13:46:12

标签: java multithreading

我必须在10个大尺寸文件中搜索一个字符串(压缩格式为70 MB),并且必须将带有搜索字符串的行打印到相应的10个输出文件中。(即文件1输出应该在output_file1中... file2 ---> output_file2)。对于单个文件,相同的程序需要15分钟。但如果使用10个线程来读取10个文件并写入10个不同的文件,它应该在15分钟内完成,但需要40分钟。

我该如何解决这个问题。或多线程只需要这么多时间?

7 个答案:

答案 0 :(得分:5)

并发访问文件通常在2-3个线程之后变慢,因为硬盘最终会同时尝试从所有文件中读取数据,类似于读取碎片整理文件。

要避免这种情况,请将工作拆分为文件读取器和文件解析器。文件读取器从文件中引入数据(也解压缩),文件解析器解析数据。您可以使用PipedInputStream / PipedOutputStream将文件读取器中的数据转发到文件解析器。

因为您的文件是压缩的,所以读取涉及I / O和cpu​​,它们可以在2-4个读取所有文件的线程中很好地交错。对于解析文件,最简单的方法就是只从PipedInputStream中读取一个线程,这样每个文件就有一个解析器线程。每个文件使用多个线程需要拆分流并处理块边界处的搜索,这会使进程复杂化,这里不需要,因为您可能有足够的并行性来处理10个解析器线程和2-4个读取器线程。

答案 1 :(得分:4)

我想你没有使用10-core-cpu-machine所以你的线程并没有真正并行运行。因此它需要比数学上更长的时间。接下来的事情是你必须要知道线程管理也需要一些时间(这是无关紧要的)。 也许你可以加快文件的搜索机制,以获得一些速度。为此,您需要发布您的源代码。 但有些人建议:

  • 你应该尽量保持文件访问次数尽可能低,因为它是最慢的操作
  • 尝试使用尽可能少的内存,因为如果你的机器开始交换内存页面,速度也会大大降低
  • 因为你在java中这样做 - 你应该使用reg-ex来查找字符串中的字符串,因为(据我记得)它是在java中搜索字符串的最快方法

但请注意,这些措施可能导致一个非常复杂的代码供另一个人或你自己阅读...让我们说六个月+因为你不记得你做过的一切以及你为什么这样做(评论;) )

答案 2 :(得分:0)

您可能有硬盘争用,多线程无效。在您的情况下,您可能只需要足够的线程来保持磁盘驱动器100%的使用率。

我假设硬盘是你的瓶颈,而不是CPU。如果每个线程不必在相同的硬件上进行争夺,则多线程只会使事情“更快”完成。因此,使用多个内核(CPU)和多个硬盘驱动器,您将看到多线程的更好性能。

我很惊讶单个文件需要15分钟。

以下是我设计的方法。 70 MB并不大。您可以将每个70 MB未压缩文件加载到内存中,每个线程一个。然后,在搜索压缩流时实时解压缩数据,在内存中保留大量未压缩数据。 (一旦你搜索过它,扔掉它)。这样可以避免硬盘颠簸,让CPU达到100%的使用率。

如果内存有问题,请从磁盘一次加载几MB。

答案 3 :(得分:0)

由于您的瓶颈将是磁盘IO,因此更多线程很可能只会让它运行得更慢。如果你可以先将所有数据加载到内存中,那么你会看到一些从多个线程加速,但只到#cores + 1,更多的只是上下文切换开销。

答案 4 :(得分:0)

当你运行它时,你的CPU是否已经100%了?如果不是,那就是两件事之一;

  • 如果它是硬盘驱动器,您可以尝试转移到更快的硬盘驱动器,RAID0条带(数据丢失危险)或RAID5。
  • 你有一个多核CPU,由于某种原因,它没有在所有内核上运行。您可以通过按CTRL-ALT-DEL,任务管理器,性能选项卡在Windows中进行一些检查。如果CPU使用历史记录在一个图表上最大化,则表明处理器未得到充分利用,并且可以考虑进行线程化。如果CPU使用率没有达到最大值,那么就会出现硬盘驱动器瓶颈,并且没有多少线程会对性能产生太大影响。如果CPU使用率到处都是最大值,那么线程化只会使速度变慢;你需要一个更快的CPU来更快地运行该任务,或者更好的算法。

答案 5 :(得分:0)

我猜这是一个GC问题。我猜你一次将这些文件读成String。也许你甚至为每一行重新编译一个正则表达式。无论如何,大量的内存分配,但短暂的对象。多个线程可能会提示足够的内容以复制到“幸存者”空间(在典型的Sun GC实现中)。我想使用visualvm或一个模糊的命令行参数来监控GC的工作难度。

也可能是锁争用问题,但这看起来很尴尬。

答案 6 :(得分:0)

你可能想看看Tim Bray创建的the "Wide Finder"项目。这听起来非常像你正在做的事情,我认为检查大多数(如果不是所有)你将遇到的问题。 HTH