随着线程数量的增加,在HDD中写入文件会变慢

时间:2014-12-15 08:52:43

标签: java multithreading

我正在使用ExecutorService创建一个多线程的env。我所有的线程都在做同样的事情。 他们从DB获取数据,使用itext准备PDF并在D盘中的某个位置编写PDF。 但我注意到一件奇怪的事情。随着我增加线程数量,我的端到端流程变得更慢。 对于1个线程 - 在1小时内生成4000 pdf 对于2个线程 - 在1小时内生成3500 pdf 对于3个线程 - 在1小时内生成3200 pdf 对于4个线程 - 在1小时内生成3000 pdf

使用logger,很明显,从DB获取数据非常快,瓶颈是PDF编写操作。

在某些地方,我在Windows中读到,与顺序写入相比,同时在同一目录下写入多个文件会变慢。 如果是,我可以实现其他逻辑以获得更高的性能。 谢谢。

环境详情

操作系统 - Windows 7,32位 RAM - 3 GB 处理器 - 酷睿i3 JDK - 1.6 DB - PostgreSql 9.3 PDF的大小 - 在500KB到2MB之间变化

2 个答案:

答案 0 :(得分:1)

写入HDD是一种IO阻塞操作,因此您不会通过多线程获得任何好处。使用硬盘驱动器,您实际上会遇到减速。如果您切换到SSD,那么您可能不会遇到执行多线程磁盘访问的速度变慢(或者至少使用HDD的速度会减慢),但是也没有任何改进。

如果您有RAID,情况可能会有所不同,但这取决于RAID的类型。

要提高场景中的性能,您应该以这种方式拆分在线程上执行的工作: 1)有一个IO线程用于从磁盘读取/写入(或者有一个IO线程用于读取,另一个IO线程用于写入 - 为此更好)。 2)有一个单独的线程进行计算。该线程不应对磁盘执行任何IO操作。

IO线程将简单地从磁盘读取数据并将数据传递到队列中(让我们将其称为“输入队列”)。然后“计算线程”从“输入队列”中获取数据,处理它,并将结果放入另一个队列(让我们将其称为“结果队列”)。然后,IO线程可以从“结果队列”中选取数据并将其写入磁盘。

答案 1 :(得分:1)

HDD一次只能写入磁盘的一部分,所以如果你有几个不同的线程(甚至是进程)同时写入,磁盘必须在整个地方移动它,写一个这里有一个位到文件A,有点到文件B那里,等等。这就是为什么它实际上较慢将这个任务分成线程,你正在使硬盘工作更加困难。

如果你有任何CPU密集型任务,它们可以经常在几个线程上进行多路复用,以便在任何现代CPU上获益,但是只要你处理像特定硬盘驱动器这样的单一资源,你就会通常最好是坚持使用单个线程来处理你正在做的事情。