【问题标题】:Read large file and process by multithreading通过多线程读取大文件和进程
【发布时间】:2019-10-08 10:09:29
【问题描述】:

我正在尝试使用 JSON 行读取一个大型(以 GB 为单位)文件,进行一些“处理”并将结果写入另一个文件。 我将为此目的使用GSON streaming API 为了加快处理速度,我想对“处理”部分进行多线程处理。 我正在逐行读取文件,因为我无法将整个文件加载到内存中。我的“处理”取决于满足某些条件的两条不同的行(可能相隔数千行)。是否可以对这种“处理”进行多线程处理,而无需将整个内容加载到内存中?

【问题讨论】:

标签: java multithreading gson


【解决方案1】:

关于如何解决这个问题有什么建议吗?

一个高级设计应该是有一个读取线程、一个写入线程和一个ExecutorService 实例来进行处理。

  • 读取器线程使用流式 API1 读取 JSON 文件。当它确定了要执行的工作单元时,它会创建一个任务并将其提交给执行器服务,然后重复。

  • 执行器服务器处理它分配的任务。您应该使用有界线程池的服务,并且可能使用有界/阻塞工作队列。

  • 编写器线程扫描任务提交创建的Future对象,并使用它们(按顺序)获取任务结果,从结果中生成输出并将输出写入文件。

如果输出文件不需要按顺序排列,您可以省去编写线程2,让任务写入文件。他们将需要使用共享锁或互斥锁,以便一次只有一个任务写入文件。

1 - 如果你不这样做,那么:1)你需要能够解析整个输入文件并将其保存在内存中,以及 2)阅读器线程将无法开始提交任务,直到它已经完成了对输入的解析。

2 - 如果它简化了事情,就这样做,而不是出于性能原因。编写时需要互斥会扼杀任何假设的性能优势。


正如@Thilo 所指出的,尝试拥有多个阅读器线程几乎没有什么收获。 (如果你尝试的话,会很复杂!)

【讨论】:

    【解决方案2】:

    我认为您将有一个从文件中读取的单个进程,它将工作人员(可运行/可调用)添加到队列中。然后,您有一个线程池,它从队列中消耗并并行执行工作人员。

    查看Executors 静态方法可以帮助创建ExecutorService

    【讨论】:

      猜你喜欢
      • 2017-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-29
      相关资源
      最近更新 更多