yohhoyの日記

技術的メモをしていきたい日記

java.util.concurrent.Phaser同期プリミティブ

Java 7で追加された java.util.concurrent.Phaser*1 同期プリミティブについてメモ。

Phaser(フェイザー)クラスは、Java 1.5からあるCountDownLatchCyclicBarrierを機能的に包含し、さらに汎用化したスレッド同期プリミティブである。CountDownLatch, CyclicBarrier, Phaserの機能比較を下表に示す。

CountDownLatch CyclicBarrier Phaser
スレッド数 固定 固定 動的変更可
再利用 ×(1回のみ)
先行可能 ×(同期バリア)
階層化 × ×
Fork/Join統合 × ×
スレッド数
同期対象となるスレッド数の指定方法。CountDownLatchとCyclicBarrierはオブジェクト構築時に指定し、以降の変更は出来ない。Phaserはオブジェクト構築後に管理スレッド数増減が可能。
再利用
一度同期処理(awaitメソッド)が行われたオブジェクト上で、再びスレッド間同期が可能か否か。CountDownLatchはオブジェクトあたり一回しか利用できない。CyclicBarrierは名前の通り循環式同期バリアのため、任意回の再利用が可能。Phaserは内部状態として「phase(フェイズ)」「終了状態」を持ち、オーバーライド(onAdvanceメソッド)によりユーザが制御することで再利用となる。
先行可能
同期プリミティブへの通知/待機処理のうち、通知処理のみを行えるか否か。CyclicBarrierでは通知・待機処理は不可分。CountDownLatch, Phaserは通知処理のみを行うメソッドが提供される。
階層化
CountDownLatch, CyclicBarrierには階層化の概念はない。Phaserオブジェクトではオブジェクト構築時に親子関係を設定でき、同期対象スレッドのサブグループ化によるスケーラビリティ改善が可能。
Fork/Join統合
Java 7で追加されたFork/Joinフレームワークとの親和性。CountDownLatch, CyclicBarrierでは特に考慮されず、待機中スレッドはブロックされたままとなる。Phaserの待機処理(await系メソッド)では、待機中スレッドにて他の実行可能ForkJoinTaskが処理されうる。

関連URL