Java多线程读取单个大文件

bob*_*bob 7 java io concurrency

什么是Java多线程应用程序的有效方法,其中许多线程必须读取完全相同的文件(大小> 1GB)并将其作为输入流公开?我注意到如果有很多线程(> 32),系统开始竞争I/O并且有很多I/O等待.

我已经考虑将文件加载到由所有线程共享的字节数组中 - 每个线程都会创建一个ByteArrayInputStream,但是分配1GB字节数组将无法正常工作.

我还考虑使用单个FileChannel,每个线程使用Channels.newInputStream()在其上创建一个InputStream,但似乎FileChannel维护InputStream的状态.

Jon*_*eet 10

在我看来,如果你想避免IO争用,你将不得不将文件加载到内存中.操作系统会做一些缓冲,但是如果你发现这还不够,你将不得不自己动手.

你真的需要32个线程吗?大概你没有那么多核心 - 所以使用更少的线程,你将获得更少的上下文切换等.

你的线程是否都从头到尾处理文件?如果是这样,你能否有效地将文件拆分成块?将第一个(比方说的)10MB数据读入内存,让所有线程处理它,然后继续下一个10MB等.

如果这不适合你,你有多少内存与文件的大小相比?如果你有足够的内存,但你不想分配一个庞大的数组,你可以将整个文件读入内存,但可以读入许多单独的较小字节数组.然后,您必须编写一个跨越所有字节数组的输入流,但这应该是可行的.


Pat*_*sen 5

您可以在只读模式下多次打开文件.您可以以任何方式访问该文件.只需将缓存留给操作系统即可.当它太慢时,您可能会考虑某种基于块的缓存,其中所有线程都可以访问相同的缓存.