GPars报告大量异步功能的状态并等待完成

时间:2012-11-15 20:39:15

标签: groovy gpars

我有一个解析器,在收集了一行的数据之后,我想激活一个异步函数并让它处理该行,而主线程继续并获得下一行。

我看过这篇文章:How do I execute two tasks simultaneously and wait for the results in Groovy?但我不确定这是否适合我的情况。

我想要做的是,在读完所有行之后,等待所有异步函数完成后再继续。使用Promises集合的一个问题是列表可能很大(100,000 +)。

另外,我想报告状态。最后,我不确定我是否要自动等待超时(比如在get()上),因为文件可能很大,但是,我确实希望允许用户因各种原因终止进程。 / p>

所以我现在所做的就是记录解析的行数(因为它们通过 rowsRead 发生),然后使用Promise的回调记录另一行正在完成处理,就像这样:

def promise = processRow(row)
promise.whenBound {
    rowsProcessed.incrementAndGet()
}

rowsProcessed 是AtomicInteger。

然后在表格末尾调用的代码中,在完成所有解析并且我正在等待处理完成之后,我这样做:

boolean test = true
while (test) {
    Thread.sleep(1000)  // No need to pound the CPU with this check
    println "read: ${sheet.rowsRead}, processed: ${sheet.rowsProcessed.get()}"
    if (sheet.rowsProcessed.get() == sheet.rowsRead) {
        test = false
    }
}

好消息是,我这里没有Promise对象的爆炸 - 只是一个简单的计数来检查。但是我不确定每次睡眠都和检查每个Promise()对象上的get()一样有效。

所以,我的问题是:

  1. 如果我使用了Promises的集合,如果执行上面的while循环的线程被Thread.interrupt()中断,get()是否会做出反应并返回?
  2. 使用Promises的集合并在每个上调用get()比尝试睡眠和检查更频繁吗?
  3. 我还没有考虑过另一种更好的方法吗?
  4. 谢谢!

2 个答案:

答案 0 :(得分:3)

  1. 调用allPromises * .get()将在等待(主)线程中断时抛出InterruptedException
  2. 是的,无论如何都已经创建了承诺,因此在我看来,将它们分组列表不应该增加额外的内存要求。
  3. 使用CountDownLanch或Phaser建议的解决方案比使用忙碌等待的IMO更合适。

答案 1 :(得分:2)

AtomicInteger的替代方法是使用CountDownLatch。它避免了sleepPromise个大对象的集合。您可以像这样使用它:

latch = new CountDownLatch(sheet.rowsRead)
...
def promise = processRow(row)
promise.whenBound {
    latch.countDown()
}
...
while (!latch.await(1, TimeUnit.SECONDS)) {
    println "read: ${sheet.rowsRead}, processed: ${sheet.rowsRead - latch.count}"
}