Java 8中的Fork-Join框架是最佳选择吗?

问题描述:

我有一个场景,就像我想要读取一个包含大约2000条记录的电子表格并将其输入到数据库中。Java 8中的Fork-Join框架是最佳选择吗?

目前我们正在使用Executor框架。我们有限制,任务不应该只有5个。每个任务从Excel中读取20行。我们提供从Excel中读取的行到每个任务的开始索引和结束索引。

说,目前,
任务1处理1-20
任务-2处理21-40
任务-3处理41-60
任务-4处理61-80
任务-5-手柄81- 100

如果任务1完成其执行,则需要接下来的20行101-120。
假设如果任务2在任务1之前完成,它将开始从121-140而不是101-120读取。

我可以在Fork-Join框架中更有效地处理这种情况,只限制5个任务和每个任务20行吗?

需要深入了解性能问题。

+2

我看不出有任何理由改变框架。 – Holger

+0

现在,任务的处理现在是由我们设计的代码完成的,即如果任务1结束,则分配下一个任务由自定义代码完成。 fork-join框架是否有任何有效的方法来处理它本身?此外,我们插入延迟等待,直到完成所有任务以获得结果。 fork-join框架本身是否处理这个问题? – dove4evr

无需切换线程池。为了使负载更加均衡你可以保持原子变量指向第一不采取行:

AtomicInteger currentRow = new AtomicInteger(); // shared between tasks 
final int maxRow = 2000; 
final int batchSize = 20; 

// Inside every task: 
while(true) { 
    int row = currentRow.getAndAdd(batchSize); 
    if(row >= maxRow) return; 
    int from = row+1; 
    int to = Math.min(row+batchSize, maxRow); 
    // process rows from..to; it's guaranteed that other threads 
    // do not process the same rows. 
} 

每个任务的主体是完全一样的。这个实现也不依赖于创建的任务数量。如果您以后决定完成3个任务或7个任务,只需调整线程池大小并提交更多(或更少)的任务。

+0

目前,该框架用于从数据库中读取数据并写入Google电子表格。问题在于,当我们编写时,第一个任务从数据库中获取100行,根据自定义逻辑过滤数据并将结果行单独写入电子表格。因此,对于开始写作的第二项任务,我们需要等到第一项任务完成后才知道第二项任务应该从哪一行开始写入。因此我想知道,如果fork-join框架本身处理这种情况。工作窃取算法在Fork-join中如何工作? – dove4evr