10

我正在使用文件作为大数据的缓存。一个线程按顺序写入,另一个线程按顺序读取。

我可以确定write()在一个线程中(由)写入的所有数据都可以read()来自另一个线程,假设在 Java 内存模型方面存在适当的“之前发生”关系?这种行为是否记录在案?

在我的 JDK 中,FileOutputStream不覆盖flush(),并且OutputStream.flush()是空的。这就是为什么我想知道...

有问题的流由我完全控制的类专有。每个流都保证只能由一个线程访问。我的测试表明它按预期工作,但我仍然想知道这是否得到保证和记录。

另请参阅此相关讨论

4

4 回答 4

11

假设您使用的是 posix 文件系统,那么是的。

FileInputStreamFileOutputStream在 *nix 上使用内部的 read 和 write 系统调用。write 的文档说读取将看到过去写入的结果

对常规文件的 write() 成功返回后:

从文件中被该写入修改的每个字节位置的任何成功 read() 都应返回 write() 为该位置指定的数据,直到再次修改此类字节位置。

我很确定 Windows 上的 ntfs 也会有同样的read() write()保证。

于 2012-10-07T21:21:14.543 回答
4

FileInputStream您不能就您和对象之间的 Java 内存模型谈论“之前发生”的关系,FileOutputStream因为它们不共享任何内存或线程。VM 可以根据您的同步要求免费重新排序它们。当您在没有应用程序级缓冲的情况下在读取和写入之间进行适当的同步时,您是安全的。

但是FileInputStreamFileOutputStream共享一个文件,这将事情留给操作系统,在主流操作系统中,您可以期望在写入后按顺序读取。

于 2012-10-07T21:23:40.697 回答
0

不,您需要 flush() 流(至少对于 Buffered(Input|Output)Streams),否则您可能在缓冲区中有数据。

也许您需要一个并发数据结构

于 2012-10-05T08:08:43.460 回答
0

如果 FileOutputStream 没有覆盖 flush(),那么我认为你可以确定 write() 写入的所有数据都可以被 read() 读取,除非你的操作系统对数据做了一些奇怪的事情(比如启动一个等待硬盘驱动器以正确的速度旋转而不是阻塞等),以便不会立即写入。

于 2012-10-07T21:19:36.660 回答