Java - 以原子方式处理文件

时间:2012-11-22 10:11:45

标签: java concurrency io

我正在编写一个Java应用程序,它应该(除其他外)生成一个整数序列,从给定的数字开始(例如900,901,902,903,... - 900作为参数给出)

  1. 当应用程序关闭然后再次启动时,当前序列值应该保持不变。
  2. 当应用程序的多个实例同时运行时,它们应该共享相同的序列(例如,所有实例生成的序列的并集应该与单个实例生成的序列相同,当单独运行时)
  3. 管理员应该能够关闭应用程序并手动重置当前序列值。
  4. 如果应用程序崩溃,该文件应始终可供其他实例访问,以便它们可以继续工作。
  5. 决定应用程序将使用仅包含当前数字的纯文本文件。当应用程序启动时,它会检查文件是否已经存在,如果没有,则创建它并将初始编号写入其中。每次应用程序即将生成一个新数字时,它应该读取文件中的当前值,将其用作当前序列值,然后递增文件中的数字。

    我现在想,如何以原子方式完成这两件事(关于同一应用程序的其他运行实例):

    • 检查文件是否存在,如果不存在,请创建文件并在其中写入数字
    • 读取文件的当前内容然后进行更改

    关于如何以其他方式实现所列目标的建议也值得赞赏。

2 个答案:

答案 0 :(得分:2)

使用数据库序列将是一个简单而可靠的解决方案,但您已确定它将是一个文件。然后,您需要自己管理分布式同步。有一些系统提供,如Terracotta或Hazelcast。我肯定会使用其中一个而不是基于锁定文件来实现一个新的。为什么不是数据库?

答案 1 :(得分:1)

当客户端写入文件时,我会创建一个锁定文件,并在写入过程完成时立即删除该锁定文件。

当存在锁定文件时,其他客户端将不会读取或写入db文件并等到锁定文件被删除 - 允许同时读取。

你有疑问:

  1. Shutdownhook
  2. 使用锁定文件mechanisem
  3. 解决
  4. 每个客户端都可以在db文件旁边创建一个ID文件,当管理员删除该文件时,客户端会关闭。
  5. 取决于:如果尊重shutdownhook这不应该是一个问题,但如果客户端立即被杀,你就没有机会清理。
  6. 问题:

    • 如果许多客户尝试编写db文件,则无法确保首先提供第一个客户端。
    • 如果客户端在写入过程中崩溃并且无法清除锁定文件,会发生什么?
    • 如果两个客户端同时尝试创建锁定文件会怎样?我认为这取决于os文件系统。