我在八个线程之间拆分计算并将结果写入文件,如下所示:
1a。七个线程中的每一个都处理其输入并将其输出写入自己的ByteArrayOutputStream
;当流关闭时,线程offers
an<Integer, ByteArrayOutputStream>
到 a ConcurrentLinkedQueue
,并调用countDown()
a CountDownLatch
(初始化为 7)。
1b。同时,第八个线程读入将在下一次迭代中处理的所有输入数据。该线程awaits
在CountDownLatch
完成读取其数据时。
2a. 当CountDownLatch
达到 0 时,第 8 个线程唤醒,ConcurrentinkedQueue
使用Integer
in<Integer, ByteArrayOutputStream>
作为排序键对 进行排序,然后遍历队列并将字节数组附加到文件中。(可能有一种更有效的方法来按顺序遍历列表而不对其进行排序,但列表中只有七个元素,因此排序方法的运行时不是问题。)
2b。同时,其他七个线程处理第八个线程为它们准备的输入。
** 此过程循环,直到处理完所有数据(通常为 40-80 次迭代)。
每个线程处理一个大小相等的输入块(可能在最后一次迭代中除外),大小为 8mb;每个ByteArrayOutputStream
包含 1-4 mb,并且无法提前知道输出大小。通常,最早完成和最新完成的 CPU 绑定线程的运行时间彼此相差 20% 以内。
我想知道是否有一个 IO 库(或者我错过的 java.io 或 java.nio 中的方法)已经做了这样的事情 - 目前第八个线程(IO 线程)空闲大约 75%时间,但是我想出的任何减轻这种低效率的方法都让我觉得太复杂了(因此在造成死锁或数据竞争方面风险太大);例如,我可以将输入分成 4 mb 块,然后将两个块分配给七个 CPU 绑定线程,一个块分配给 IO 绑定线程,这在理论上可以将 IO 线程的空闲时间减少到 25%(25% on IO,50% 在 4 mb 块上,25% 空闲),但这是一个脆弱的解决方案,可能无法移植到另一个 CPU(这意味着在另一个 CPU 上,IO 绑定线程可能会变成一个瓶颈,例如它的运行时间是CPU 绑定线程的 150%) - 我'