Java 7で追加された java.util.concurrent.Phaser*1 同期プリミティブについてメモ。
Phaser(フェイザー)クラスは、Java 1.5からあるCountDownLatchやCyclicBarrierを機能的に包含し、さらに汎用化したスレッド同期プリミティブである。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