【问题标题】:Concurrency while reading files from file system从文件系统读取文件时的并发
【发布时间】:2011-11-15 14:19:36
【问题描述】:

我们有一个应用程序从特定文件夹读取文件,处理它们并将其复制(一些业务逻辑)到另一个文件夹。

这里的问题是当需要处理大量文件时,运行应用程序的单个实例或单个线程已不足以处理这些文件。

我们为此采取的一种方法是启动应用程序的多个实例(我觉得这种方法有问题。如果有的话,请给我建议一个替代方案)。

产生线程或启动应用程序的多个实例,应注意,如果一个线程读取一个文件并开始处理它,另一个线程不应该拾取它。

我们试图通过一个包含文件夹中文件名列表的数据库表来实现这一点,这样当线程第一次读取表中的文件名时,我们将更改状态到 in-processcompleted 并悲观地锁定表,使其他线程无法读取它。

有没有更好的办法解决这个问题?

【问题讨论】:

  • 您需要确保磁盘子系统不是您的瓶颈。如果 CPU 或外部服务(例如数据库是你的瓶颈。

标签: java multithreading concurrency filesystems locking


【解决方案1】:

您可以将现有的大部分实现用作前端处理器,将文件流提供给工作线程,您可以根据需要启动/停止这些工作线程。只有前端线程打开文件,因此没有一个工作人员干扰另一个工作人员的可能性。

编辑:添加了“不”这个词,因为它改变了很多意思......

【讨论】:

    【解决方案2】:

    还可以看看 JDK 7。它有一个新的文件 I/O API 和一个可能会有所帮助的 fork/join 框架。

    【讨论】:

      【解决方案3】:

      看看 Apache Camel (http://camel.apache.org) 及其文件组件 (http://camel.apache.org/file2.html)。使用 Camel,您可以非常轻松地定义一组处理指令来原子地使用目录中的文件,还可以配置线程池以同时处理多个文件。 Camel in Action 是一本帮助您入门的好书。

      【讨论】:

        【解决方案4】:

        你的描述让我想起了在 UNIX 上开发的经典风格。

        在这种古典风格中,您可以将文件移动到正在进行的工作目录中,这样其他文件就不会拾取它。一般来说:您可以为每个处理状态使用一个目录,而不是将文件从一个状态移动到另一个状态。

        这主要是因为file moves are atomic(至少在 Unix 系统和 NFTS 下)。

        这种方法的好处在于,它可以很容易地处理诸如崩溃之类的问题情况,并且它自动具有每个人都熟悉的良好管理界面(文件系统 GUI、ls、Windows 资源管理器......)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-12
          • 1970-01-01
          相关资源
          最近更新 更多