Java NIO FileLock 允许其他进程写入锁定的文件

Posted

技术标签:

【中文标题】Java NIO FileLock 允许其他进程写入锁定的文件【英文标题】:Java NIO FileLock allows other process to write to a locked file 【发布时间】:2019-10-20 19:59:24 【问题描述】:

我正在使用以下代码在一个 Java 应用程序中获取对文件的锁定:

...

File file = new File("/some/file/at/some/path.txt");
FileChannel channel = new RandomAccessFile(file, "rw").getChannel();

FileLock lock = channel.tryLock();

if (lock != null) 
    Thread.sleep(60000); // Hold lock for 60 seconds 
    lock.release();


...

如果在上述 60 秒内,我使用以下代码运行另一个 java 应用程序,它无法获取锁(如预期的那样),但它仍然可以写入。

...

File file = new File("/some/file/at/some/path.txt");
System.out.println(file.canWrite());  // returns true (not expected)

FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
FileLock lock = channel.tryLock();  
System.out.println(lock.toString());  // throws NullPointerException (expected)

...

同一个文件(当第一个应用程序持有锁时)也可由非 Java 应用程序(例如 vi、bash 等)写入。 Oracle docs 表示锁定映射到底层操作系统的本机锁定,因此对所有程序可见。因此,我希望锁定能够阻止任何其他进程在其上写入。

我的代码或理解中是否遗漏了什么?

我在 MacOS Mojave (10.14) 上运行上述代码。

【问题讨论】:

【参考方案1】:

它还在您链接到“锁是否实际上阻止另一个程序访问锁定区域的内容是系统相关的,因此未指定”的文档中说。

所以这取决于操作系统是否能够进行写锁定。

【讨论】:

对。是否有任何关于 FileLock 在各种操作系统上的行为的官方/非官方文档? 我不知道。您需要检查操作系统的特定版本和您正在运行的 JVM 版本。 是否至少可以保证在一个 JVM 上运行的应用程序在检查时可以看到另一个 JVM 中的应用程序获取的锁?就像我的问题中的一个例子。或者这也是特定于操作系统的? 我不相信这是指定的,并且将再次取决于操作系统的锁定方法。文档指出,这些锁应被视为建议性的。 我的猜测是文件锁在任何地方都是建议性的,除了在 Windows 上,但不要引用我的话。

以上是关于Java NIO FileLock 允许其他进程写入锁定的文件的主要内容,如果未能解决你的问题,请参考以下文章

死磕NIO— 跨进程文件锁:FileLock

死磕NIO— 跨进程文件锁:FileLock

死磕NIO— 跨进程文件锁:FileLock

死磕NIO— 跨进程文件锁:FileLock

Java NIO总结

NIO--FileLock,Path,Files,AsynchronousFileChannel,Charset