0

以下 Java 代码是否保证对 Windows 中未打开的文件进行排他锁定?

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test {
    public static void main(String[] args) {
        File file = new File("mylog.log");
        try {
            FileOutputStream fos = new FileOutputStream(file);
            fos.getChannel().lock();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
4

3 回答 3

1

tl;dr:不。您不能对主机操作系统处理您的锁的行为做出假设。

好消息:您是否试图确保在您的应用程序中拥有线程安全的锁定机制?如果是这样,FileLock就足够了(当然,假设应用程序的其余部分由正确编写的线程安全代码组成)。

坏消息:不幸的是,如果您试图确保 Windows 将兑现您对所有应用程序的锁定,您就不能指望这一点。

这在 Windows 中很容易观察到:您通常可以覆盖正在写入的文件(例如,当日志文件变得太长时,我让 emacs 删除所有以前的垃圾邮件)。也就是说,Windows 通常不允许您删除打开的文件。

从 FileLock 文档

文件锁代表整个 Java 虚拟机持有。它们不适用于控制同一虚拟机内的多个线程对文件的访问。

文件锁对象可以安全地被多个并发线程使用。

... 然后 ...

锁是否实际上阻止另一个程序访问锁定区域的内容是系统相关的,因此未指定。某些系统的本机文件锁定工具只是建议性的,这意味着程序必须协同遵守已知的锁定协议以保证数据完整性。在其他系统上,本地文件锁是强制性的,这意味着如果一个程序锁定了文件的某个区域,那么实际上会阻止其他程序以违反锁的方式访问该区域。在其他系统上,本机文件锁是建议性的还是强制性的,可以根据每个文件进行配置。为确保跨平台的一致和正确行为,

于 2010-07-08T13:36:27.390 回答
1

正如在 Java 规范中所见:

文件锁代表整个 Java 虚拟机持有。它们不适用于控制同一虚拟机内的多个线程对文件的访问。

所以如果你需要线程独占锁,请选择其他方式。

于 2010-07-08T12:08:13.017 回答
0

即使您对文件使用锁定和解锁标志,您也只能保证您在 Java 应用程序中具有排他锁。

您必须使用 JNI 或其他计算机语言来进行 Windows 调用以保证对 Windows 文件的独占锁定。

Windows LockFile函数

Windows解锁文件功能

于 2010-07-08T13:14:50.047 回答