Go の WaitGroup
は、複数のスレッドに処理を振り分けて、すべての処理が完了するまで待つような用途で便利。Java で Go の WaitGroup
に似たものとして、標準ライブラリに CountDownLatch
がある。
(コード例は Kotlin)
もっと簡単に Parallel Stream でもいける。
しかし、Java におけるいずれのやり方も、以下の WaitGroup
の利用ケースのように、処理すべき要素の数が未知である場合には対応できない。Parallel Stream は一見できそうに見えるが、内部で ForkJoinPool
というクラスを使っている都合上、事前に要素数がわかっている必要があるようだった。
例だと tasks
は3要素なので、先にチャネルからすべての要素を受け取ってしまえばよいと思うかもしれない。しかし、ここにメモリに乗り切らないような量で要素数も未知のデータが流れてくる場合には、順次読み進めながら task
の処理をディスパッチしていくようにしたい。
調べてみたところ、このような場合に使えるものとして Phaser
というクラスがあることを知った。
register
は Add
、arrive
は Done
、arriveAndAwaitAdvance
は Wait
にそれぞれ対応しており、Go で WaitGroup
を使った場合と似たような使い勝手を実現できている。Java 的にはもうちょっとラップしてあげるほうがらしい気はするが。