2011-03-02 128 views
1

我有一个250MB的文件被读取。而且该应用程序是多线程的。如果我允许所有线程读取文件内存饥饿发生。 我得到内存不足的错误。通过多线程读取文件

为了避免它。我想在内存中只有一个字符串(从流中读取)的副本,我希望所有线程都使用它。

while (true) { 
    synchronized (buffer) { 
     num = is.read(buffer); 
      String str = new String(buffer, 0, num); 

    } 
    sendToPC(str); 
} 

基本上我想只有一个字符串的副本时,所有线程完成发送,我想读取第二个字符串等。

+0

@Dheeraj是ü谈论由多个线程共享串的每一行从一个文件中。 – 2011-03-02 08:54:22

+0

是的。我是...... – 2011-03-02 08:55:16

+0

@Dheeraj你想通过使用多个线程达到目标。 – 2011-03-02 08:56:51

回答

6

为什么多个线程?你只有一个磁盘,它只能运行得如此之快。多线程几乎肯定无济于事。而任何依靠内存中的整个文件进行的软件设计首先都是严重缺陷的。

假设你定义了你的问题?

+0

要清楚一些要点。我想将文件推送到多台计算机。 – 2011-03-02 08:56:12

+4

@Dheeraj:然后在*一个线程*中读取文件,并使用单独的工作线程将数据推送到其他计算机。 – dacwe 2011-03-02 08:59:51

+2

我并不完全同意你的答案,但也许这取决于它的解释。在游戏开发中,需要加载大量数据,我们需要尽快加载。当然,控制台是有限的,所以你可能无法做到这一点,但在PC上,将文件预加载到内存然后进行处理要快得多。实际上,在我正在研究的游戏引擎中,我正在改变我的内容加载器以使用数据流,而不是直接访问文件,因此我可以选择预先加载文件以提供足够的内存;我不喜欢加载时间,这是加快速度的一个简单方法。 – leetNightshade 2012-03-19 17:37:21

1

您可以直接使用流而不是完全读取文件到内存吗?

+1

不,现在不幸。它是这样写的。我现在需要做内存优化。接收器只接收字符串和文件作为部分。 – 2011-03-02 09:02:21

1

您可以在File reading class中将所有线程注册为回调。所以有类似数组或列表的类实现了一个接口StringReaderThread,它具有processString(String input)方法。在读取文件中的每一行后,迭代这个数组/列表,并在所有线程上调用processString()。这会解决你的问题吗?

2

我意识到这是一种迟到,但我认为你在这里想要的是在FileChannel类中使用map函数。一旦将文件的某个区域映射到内存中,则所有线程都可以读取或写入该内存块,操作系统会定期将该内存区域与该文件同步(或调用MappedByteBuffer.load()时),以及如果您希望每个线程都与文件的不同部分一起工作,则可以分配几个映射,每个映射映射文件的特定区域,并且每个线程只使用一个映射。

看到的Javadoc FileChannelRandomAccessFileMappedByteBuffer