並行コレクション・クラス
メモ:
- Doug Lea 氏の util.concurrent がいけてる
- Map の歴史
- Hashtable: JDK 1.0 登場。同期化された Map。同期化が必要ない場合に遅い。
- HashMap と Collections.synchronizedMap: JDK1.2 で登場。同期化されない基底クラスと同期化されたラッパークラスで使い分けが可能に。
- Hashtable と HashMap の問題点
- 両者ともテーブルにアクセスできるスレッドは一つだけというスケーラビリティの問題
- イテレーション・put-if-absent などの復号オペレーションには追加の同期が必要という問題
- これは特に「条件付きスレッド・セーフ」と呼び、開発者に誤った認識を与える
- Hashtable などは一個のロックで同期化するのでスケーラビリティがなくなる
- ロックの粒度を低くすることで解決できる(ハッシュバケットごとのロックなど)
- それでも size() や isEmpty() を使おうとすると、全部のロックが必要になる
- ConcurrentHashMap の登場
- ポイント:呼び出し側との決めごとを緩めることでパフォーマンスをあげる
- get は直近の値かもしれないし、同時進行中の設定中の値かもしれない
- イテレータは追加・削除を反映するかもしれないし、反映しないかもしれない
- CopyOnWriteArrayList
- 変更時にだけロックする Array
- 実装:不変配列の可変参照をもっている。 変更時に参照を付け替える。
- イテレータは不変配列を参照するのでおかしくはならない。
- 読み取りが多い場合向け
- 結論
- 完全な同期化を提供する Hastable、Vector の完全な代替にはならない。
- ただし、たいていの場合 CopyOnWriteArrayList と ConcurrentHashMap で問題ない。