考虑以下场景:
- 进程1(Writer)连续向文件追加一行(sharedFile.txt
- 进程2(Reader)连续读取sharedFile.txt中的一行
我的问题是:
在java中有可能:
- Reader进程以某种方式崩溃Writer过程(即中断Writer的进程)
- Reader有些人完全根据文件统计信息知道何时停止读取文件(Reader不知道其他人是否正在写入文件)
使降级
处理一(写入程序):
...
while(!done){
String nextLine;//process the line
writeLine(nextLine);
...
}
...
流程二(读卡器):
...
while(hasNextLine()){
String nextLine= readLine();
...
}
...
注意:
写入程序进程具有优先级。所以任何东西都不能干扰它。
由于您谈论的是进程,而不是线程。答案取决于底层操作系统如何管理打开的文件句柄:
- 在我熟悉的每一个操作系统上,Reader都不会破坏写入程序进程,因为Reader的文件句柄只允许读取。在Linux上,读卡器可能在底层操作系统上调用的系统调用是带有
O_RDONLY
标志的open(2)
、lseek(2)
和read(2)
——已知不会干扰写入器正在调用的系统呼叫,如write(2)
- 在大多数操作系统上,读者很可能不知道何时停止阅读。更准确地说,在一些读取尝试中,它将接收到零作为读取字节数,并将其视为EOF(文件结尾)。此时此刻,Writer可能正准备将一些数据附加到文件中,但Reader却无从知晓
如果您需要一种让两个进程通过文件进行通信的方式,您可以使用一些额外的文件来实现,这些文件在Readers和Writers之间传递元信息,例如当前是否有Writer正在运行。在文件中引入一些结构也很有用(例如,每个Writer都会在文件中添加一个字节,表示写入过程正在进行)。
对于非常快速的非阻塞I/O,您可能需要考虑通过Java的MappedByteBuffer
进行内存映射的文件。
代码不会崩溃。然而,当到达终点时,读者将终止,即使作者可能仍在写作。你必须以某种方式同步!
问题:
即使您认为另一个编写器线程已经更新了变量值,您的读取器线程也可以读取过时的值
即使在没有同步的情况下写入文件,在读取时也会看到不同的值
Java File IO和普通文件不是为同时写入和读取而设计的。要么你的读者会超过你的作者,要么你的阅读永远不会完成。
JB Nizet在评论中给出了答案。在读取写入程序数据时,您使用BlockingQueue来保存写入程序数据。队列将为空,或者读取器永远不会完成。您可以通过BlockingQueue方法检测任何一种情况。