我使用文件作为大数据的缓存。一个线程按顺序写入,另一个线程按顺序读取它。
我可以确定在一个线程中编写的所有数据(由write()
编写)可以是来自另一个线程的read()
,假设在Java内存模型方面存在适当的“先发生”关系吗?这种行为是否有记录?
在我的JDK中,FileOutputStream
不会覆盖flush()
,而OutputStream.flush()
是空的。这就是我想知道的原因......
有问题的流程完全由我完全控制的类所有。保证每个流只能由一个线程访问。我的测试显示它按预期工作,但我仍然想知道这是否有保证和记录。
假设您使用的是posix文件系统,那么是的。
* nix上的FileInputStream
和FileOutputStream
在内部使用读写系统调用。写的文件说reads will see the results of past writes,
在成功返回常规文件的write()之后:
从该写入修改的文件中每个字节位置的任何成功read()都将返回该位置的write()指定的数据,直到再次修改这些字节位置。
我很确定Windows上的ntfs将具有相同的read()
write()
保证。
你不能谈论你的FileInputStream
和FileOutputStream
对象之间的Java内存模型之间的“发生之前”关系,因为它们不共享任何内存或线程。 VM可以自由重新排序,只是为了满足您的同步要求。如果在没有应用程序级缓冲的情况下在读写之间进行适当的同步,那么您就是安全的。
然而,FileInputStream
和FileOutputStream
共享一个文件,这会将操作系统留给操作系统,在按顺序写入后,您可以期望读取主流操作系统中的操作系统。
不,你需要flush()Streams(至少对于Buffered(输入|输出)Streams),否则你可能在缓冲区中有数据。
也许你需要一个concurrent data structure?
如果FileOutputStream没有覆盖flush(),那么我认为你可以确定write()写的所有数据都可以被read()读取,除非你的操作系统对数据做了一些奇怪的事情(比如启动一个等待硬盘驱动器以正确的速度旋转而不是阻塞等,这样它就不会立即写入。