以下 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();
        }
    }
}
有帮助吗?

解决方案

可以在Java规范中看到:

文件锁代表整个Java虚拟机保留。它们不适合通过同一虚拟机内的多个线程控制对文件的访问。

因此,如果您需要针对线程的独占锁,请选择另一种方式。

其他提示

长话短说: 不。您不能对主机操作系统处理锁的行为做出假设。

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

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

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

来自 FileLock 文档:

文件锁是代表 整个 Java 虚拟机。他们是 不适合控制对 一个由多个线程组成的文件 相同的虚拟机。

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

...然后 ...

是否真的是锁 防止其他程序 访问锁定的内容 region 依赖于系统,并且 因此未指定。原生的 一些文件锁定设施 系统只是建议性的,这意味着 这些计划必须合作 遵守 以保证数据完整性。上 其他系统本机文件锁是 强制,这意味着如果一个程序 先锁定文件的某个区域,然后锁定其他区域 程序实际上被阻止 以以下方式访问该区域 会违反锁。在其他 系统,本机文件锁是否 建议或强制是可配置的 基于每个文件。为确保 跨 平台,强烈推荐 此 API 提供的锁是 用作咨询锁。

即使您使用锁定和解锁文件的标志,您也只能保证您在Java应用程序中拥有独占锁定

必须使用JNI或其他计算机语言,使Windows呼叫保证Windows文件上的独占锁定。

windows lockfile 功能

windows 解锁文件功能

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top