读取大文件并通过多线程处理
Read large file and process by multithreading
我正在尝试读取一个包含 JSON 行的大型(以 GB 为单位)文件,执行一些 'processing' 并将结果写入另一个文件。
我将使用 GSON streaming API 来达到目的。
为了加快处理速度,我想对 'processsing' 部分进行多线程处理。
我正在逐行读取文件,因为我无法将整个文件加载到内存中。我的 'processing' 取决于满足特定条件的两条不同的线(可能相隔数千行)。是否可以对这个 'processing' 进行多线程处理,而无需将整个内容加载到内存中?
我认为您将有一个进程从文件中读取数据,该进程将工作人员 (Runnable/Callable) 添加到队列中。然后你有一个线程池,它从队列中消耗并并行执行工作人员。
参见 Executors static methods which can help creating a ExecutorService
Any suggestions on how to go about this ?
高级设计应该有一个 reader 线程、一个编写器线程和一个 ExecutorService
实例来进行处理。
reader 线程使用流 API1 读取 JSON 文件。当它确定要执行的工作单元时,它会创建一个任务并将其提交给执行程序服务,然后重复。
执行服务器处理给它的任务。您应该使用具有有界线程池的服务,可能还有有界/阻塞工作队列。
writer线程扫描任务提交创建的Future
个对象,并使用它们获取任务结果(按顺序),从结果中生成输出并将输出写入文件。
如果输出文件不需要按顺序排列,您可以省去写入线程2,让任务写入文件。他们将需要使用共享锁或互斥锁,以便一次只有一个任务写入文件。
1 - 如果您不这样做,则:1) 您需要能够解析整个输入文件并将其保存在内存中,并且 2) reader 线程不会在完成对输入的解析之前,无法开始提交任务。
2 - 如果这样做可以简化事情,而不是出于性能原因,请执行此操作。写入时需要互斥会破坏任何假设的性能优势。
正如@Thilo 指出的那样,尝试拥有多个 reader 线程几乎无济于事。 (如果你尝试的话,还有很多复杂性!)
我正在尝试读取一个包含 JSON 行的大型(以 GB 为单位)文件,执行一些 'processing' 并将结果写入另一个文件。
我将使用 GSON streaming API 来达到目的。
为了加快处理速度,我想对 'processsing' 部分进行多线程处理。
我正在逐行读取文件,因为我无法将整个文件加载到内存中。我的 'processing' 取决于满足特定条件的两条不同的线(可能相隔数千行)。是否可以对这个 'processing' 进行多线程处理,而无需将整个内容加载到内存中?
我认为您将有一个进程从文件中读取数据,该进程将工作人员 (Runnable/Callable) 添加到队列中。然后你有一个线程池,它从队列中消耗并并行执行工作人员。
参见 Executors static methods which can help creating a ExecutorService
Any suggestions on how to go about this ?
高级设计应该有一个 reader 线程、一个编写器线程和一个 ExecutorService
实例来进行处理。
reader 线程使用流 API1 读取 JSON 文件。当它确定要执行的工作单元时,它会创建一个任务并将其提交给执行程序服务,然后重复。
执行服务器处理给它的任务。您应该使用具有有界线程池的服务,可能还有有界/阻塞工作队列。
writer线程扫描任务提交创建的
Future
个对象,并使用它们获取任务结果(按顺序),从结果中生成输出并将输出写入文件。
如果输出文件不需要按顺序排列,您可以省去写入线程2,让任务写入文件。他们将需要使用共享锁或互斥锁,以便一次只有一个任务写入文件。
1 - 如果您不这样做,则:1) 您需要能够解析整个输入文件并将其保存在内存中,并且 2) reader 线程不会在完成对输入的解析之前,无法开始提交任务。
2 - 如果这样做可以简化事情,而不是出于性能原因,请执行此操作。写入时需要互斥会破坏任何假设的性能优势。
正如@Thilo 指出的那样,尝试拥有多个 reader 线程几乎无济于事。 (如果你尝试的话,还有很多复杂性!)