我有一个解析器,在收集了一行的数据之后,我想激活一个异步函数并让它处理该行,而主线程继续并获得下一行。
我看过这篇文章: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()一样有效。
所以,我的问题是:
谢谢!
答案 0 :(得分:3)
答案 1 :(得分:2)
AtomicInteger
的替代方法是使用CountDownLatch
。它避免了sleep
和Promise
个大对象的集合。您可以像这样使用它:
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}"
}