繁体   English   中英

java.io.File.createNewFile()是否在网络文件系统中是原子的?

[英]Is java.io.File.createNewFile() atomic in a network file system?

编辑:嗯,我回来了几个月后,我试图编码的锁机制不起作用,因为createNewFile在NFS上不可靠。 检查下面的答案。


这是我的情况:我只有一个可以访问文件的应用程序,因此我对其他应用程序可能执行的操作没有任何限制,但是为了冗余和性能目的,应用程序在生产环境中的多个服务器上同时运行(有几台机器正在使用我们的应用程序托管每个JVM。

基本上,我需要的是在文件夹中放置某种标志,以告诉其他实例单独保留此文件夹,因为另一个实例已经在处理它。


许多搜索结果都告诉我们使用FileLock来实现这一目标,但是我检查了Javadoc,根据我的理解它不会有太大帮助,因为它使用托管操作系统的锁定可能性。 所以我怀疑它会有很大帮助,因为有不同的托管机器。

这个问题涵盖了一个类似的主题: 网络上的Java文件锁定 ,并且接受的答案是建议实现您自己的协作锁定过程(使用OP提出的File.createNewFile() )。


File.createNewFile()的Javadoc表示如果该文件尚不存在,该过程将自动创建该文件。 这在网络文件系统中是否可靠?

我的意思是,潜在的网络延迟如何同时进行存在检查和创建?

检查文件是否存在以及文件的创建(如果不存在)是针对可能影响文件的所有其他文件系统活动的原子操作。

不, createNewFile在网络文件系统上无法正常工作。

即使系统调用是原子的,它只是关于操作系统的原子,而不是通过网络。 随着时间的推移,我遇到了几次碰撞,比如每2-3个月一次(大约每600k文件一次)。

发生的事情是我的程序在2个独立的服务器上运行6个实例,所以让我们称它们为A1,A2,A3和B1,B2,B3。
当A1,A2和A3尝试创建相同的文件时,操作系统可以正确地确保只创建一个文件,因为它正在使用它自己。
当A1和B1尝试在同一时刻创建相同的文件时,会出现某种形式的网络缓存和/或网络延迟,并且它们都从File.createNewFile()获得true返回。
然后我的代码通过重命名父文件夹来停止程序的其他实例,从而不必要地尝试处理文件夹,这就是它失败的地方:

  • 在A1上,文件夹重命名操作成功,但无法删除锁定文件,因此A1只是让它这样,并继续处理新的传入文件夹。
  • 在B1上,文件夹重命名操作( File.renameTo() ,无法修复它)陷入无限循环,因为文件夹已经重命名(根据我的系统管理员也导致巨大的I / O流量),在重新启动程序之前,B1无法处理任何新文件。

检查文件是否存在以及文件的创建(如果不存在)是针对可能影响文件的所有其他文件系统活动的原子操作。

这可以通过open()系统调用或我曾经使用过的任何操作系统中的等价物轻松实现。

我的意思是,潜在的网络延迟如何同时进行存在检查和创建?

同时原子之间存在差异。 Java doc并没有说这个函数是一组两个同步动作,而是两个旨在以原子方式工作的动作。 如果构建此方法以原子方式执行两个操作而不是在没有先检查文件存在的情况下永远不会创建文件,并且如果文件由当前调用创建,则表示没有文件存在且文件未创建意味着存在已经是该名称的文件。

尽管呼叫在网络或本地磁盘上,但我没有理由怀疑功能是原子的还是可靠的。 本地呼叫同样不可靠 - 在IO中可能出现很多问题。

当你尝试使用这个函数创建的空文件作为Lock时,你不得不怀疑这是D-Mac对这个问题的回答, 也是Java Doc中为这个函数明确提到的。

你正在寻找一个目录锁和空文件作为目录锁(以指示其他进程和线程不接触它)已经很好地为我工作提供了应当小心写逻辑来检查文件是否存在,锁定文件清理向上和孤立的锁。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM