【问题标题】:Concurrent file write in Java on Windows在 Windows 上用 Java 并发文件写入
【发布时间】:2009-04-03 11:25:51
【问题描述】:

当您在同一个文件上同时打开两个(或更多)FileOutputStreams 时会发生什么?

Java API 是这样说的:

特别是某些平台,一次只允许一个 FileOutputStream(或其他文件写入对象)打开一个文件进行写入。

我猜 Windows 不是这样的平台,因为我有两个线程读取一些大文件(每个都是不同的),然后将其写入同一个输出文件。没有抛出异常,文件被创建并且似乎包含来自两个输入文件的块。

附加问题:

  • Unix 也是这样吗?
  • 而且由于我希望行为相同(实际上我希望一个线程正确写入,另一个线程被警告冲突),我如何确定文件已经打开以进行写入?

【问题讨论】:

    标签: java file-io portability concurrency


    【解决方案1】:

    当文件有另一个写入者时,没有一种可靠的跨平台方法可以被动地通知 - 即,如果文件已经打开以进行写入,则引发异常。不过,有几种技术可以帮助您主动检查这一点。

    如果多个进程(可以是 Java 和非 Java 的混合)可能正在使用该文件,请使用 FileLock。成功使用文件锁的关键是记住它们只是“建议”。如果您检查它,则可以保证该锁是可见的,但如果您忘记了,它不会阻止您对文件执行操作。所有访问文件的进程都应设计为使用锁定协议。

    如果单个 Java 进程正在处理该文件,您可以使用 Java 内置的并发工具来安全地执行此操作。您需要一个对所有线程可见的映射,它将每个文件名与其对应的锁实例相关联。 a related question 的答案可以很容易地调整为使用 File 对象或 canonical paths 到文件来执行此操作。锁定对象可以是FileOutputStream、流周围的一些包装器或ReentrantReadWriteLock.

    【讨论】:

      【解决方案2】:

      我会警惕让操作系统为您确定文件状态(因为这取决于操作系统)。如果您有共享资源,我会使用 Re-entrant lock 限制对它的访问

      使用这个锁意味着一个线程可以获取资源(文件)并写入它。下一个线程可以检查这个锁是否被另一个线程持有,和/或无限期地阻塞直到第一个线程释放它。

      Windows(我认为)会限制两个进程写入同一个文件。我不相信 Unix 会这样做。

      【讨论】:

      • 但是我不想在我写的时候阻塞,我想阻塞,如果有人已经在写我想写的文件。实际上,我根本不想阻止。我想告诉第二个线程他不能写,让客户决定进一步的行动。
      • 检查那个锁 API。您将能够检查锁以确定其他人是否已将其锁定(即未锁定),然后决定做什么
      【解决方案3】:

      如果您所说的 2 个线程在同一个 JVM 中,那么您可以在某个地方有一个可供两个线程访问的布尔变量。

      【讨论】:

        【解决方案4】:

        Unix 允许并发写入同一文件。

        您不应该多次尝试写入同一个文件。如果你是,你有一个设计缺陷。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-03-31
          • 1970-01-01
          • 1970-01-01
          • 2021-02-13
          • 1970-01-01
          • 2012-12-03
          • 1970-01-01
          相关资源
          最近更新 更多