gpt4 book ai didi

java - 如何最好地在 Java 集群中锁定文件

转载 作者:搜寻专家 更新时间:2023-11-01 03:47:58 25 4
gpt4 key购买 nike

我有一个在 JBoss 上运行的服务器集群。我需要以安全的方式更新文件。具体来说,我需要

  1. 锁定文件 A——如果它已经被锁定,则以一种安全的方式进行阻塞,这样如果 JVM 突然死机,就不会有悬空锁。 30 秒的超时就可以了。
  2. 阅读文件A
  3. 修改内容
  4. 将文件写入临时名称A.tmp
  5. 删除原文件A
  6. 将 A.tmp 重命名为正确的名称 A
  7. 解锁文件A

当我查看 java.nio.FileLock 时,它似乎与 InputStream 相关联。我真的只需要锁定一个抽象名称。我不需要锁定文件的一部分。如果这是最佳选择,我可以为此创建一个锁定文件(与数据文件分开)。但是我的问题的要点是我需要在读取之前获取锁,然后在更新文件后释放锁。请注意,我以某种方式更新文件以确保我在文件系统上永远不会有部分写入的文件。我需要写入整个文件,然后在写入后重命名它,以确保拥有该名称的任何文件都具有完整的内容集,并且如果进程在写入过程中死亡,它会留下一个可以轻松清理的临时文件稍后。

java.nio.FileLock 真的适合这种用途吗?还是我应该看看其他东西?

最佳答案

这是我最后做的。对于名为“XXX”的每个文件,我使用一个名为“XXX#LOCK”的零长度锁定文件

  1. 我使用 RandomAccessFile 锁定它以进行更新。

  2. 当这个锁定文件被锁定时,我操作实际的有问题的文件:读取原始文件、流式传输到临时文件、删除原始文件以及重命名临时文件等。

  3. 我解锁了锁文件

锁定代码:

    File lockFile = new File(target.getParent(), target.getName() + "#LOCK");
lockAccessFile = new RandomAccessFile(lockFile, "rw");
FileChannel lockChannel = lockAccessFile.getChannel();
lock = lockChannel.lock();

解锁代码:

    if (lock != null) {
lock.release();
lock = null;
}
if (lockAccessFile != null) {
lockAccessFile.close();
lockAccessFile = null;
}

我将其包装在一个类中,该类将锁定和解锁与原始文件的读取或写入一起进行。可以看到,locklockAccessFile是成员变量。

我实际上从未向锁定文件写入任何内容,但它们存在于文件夹中。由于我有少量文件要以这种方式管理(其中 6 个),我只是将 LOCK 文件留在那里作为开销,虽然丑陋但无害。

这适用于跨多主机集群的我的代码,因为我的代码是唯一操纵这些文件的东西。最大的问题是,如果其他一些代码在不知道这个约定的情况下开始操作文件,就会导致问题。我还没有找到任何证据表明有一种标准的方法来处理这个问题,该方法将由操作系统强制执行,同时由 Java 支持。如果您知道,请告诉我。

关于java - 如何最好地在 Java 集群中锁定文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38526966/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com