2

パーサーがあり、行のデータを収集した後、メイン スレッドが続行して次の行を取得している間に、aync 関数を起動して行を処理させたいと考えています。

この投稿を見たことがあります: Groovy で 2 つのタスクを同時に実行し、結果を待つにはどうすればよいですか? しかし、それが私の状況に最適な解決策であるかどうかはわかりません。

私がやりたいことは、すべての行が読み取られた後、すべての非同期関数が完了するのを待ってから先に進むことです。Promise のコレクションを使用する際の懸念事項の 1 つは、リストが大きくなる可能性があることです (100,000 以上)。

また、進行状況を報告したいと思います。最後に、ファイルが巨大になる可能性があるため、(get() のように) タイムアウトを自動的に待ちたいかどうかはわかりませんが、ユーザーがさまざまな理由でプロセスを強制終了できるようにしたいと考えています。

したがって、今のところ行ったことは、解析された行の数を記録し ( rowReadを介して発生するため)、次のように 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. Promise のコレクションを使用し、それぞれで get() を呼び出す方が、頻繁にスリープしてチェックするよりも効率的でしょうか?
  3. 私が考慮していない別のより良いアプローチはありますか?

ありがとう!

4

2 に答える 2

3
  1. allPromises*.get() を呼び出すと、待機中の (メイン) スレッドが中断された場合、InterruptedException がスローされます。
  2. はい、プロミスはとにかく作成されているので、私の意見では、それらをリストにグループ化することで追加のメモリ要件が課されることはありません。
  3. CountDownLanch または Phaser を使用した提案されたソリューションは、ビジー待機を使用するよりもはるかに適しています。
于 2012-11-16T10:35:06.143 に答える
2

An alternative to an AtomicInteger is to use a CountDownLatch. It avoids both the sleep and the large collection of Promise objects. You could use it like this:

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}"
}
于 2012-11-15T21:19:39.177 に答える