- PR -

HashMapの同期について

1
投稿者投稿内容
Tol
常連さん
会議室デビュー日: 2004/07/16
投稿数: 27
投稿日時: 2006-05-21 15:10
マルチスレッド環境でHashMapをキャッシュ用途に使用しています。
具体的には、起動時にプロパティファイルから値を読み出しMapに格納して、
それ以降はgetメソッドで値の読み出ししか行っていません。
起動時のみシングルスレッドでプロパティファイルを読み込み、
それ以降はマルチスレッドでgetメソッドを使用しています。

こういう用途の場合にでもHashMapは同期化をする必要があるのでしょうか?
Collection#synchronizedMapを使用するとgetメソッドも同期化
されるみたいなのですが、getメソッドの同期は必要ないのであれば、
効率が悪くなってしまうのではないかと思っています。

マルチスレッドで、putやremoveを使用するのであれば、getメソッドについても
同期をとる必要があるのはわかるのですが、getしか使用しない場合に同期を
とる必要があるのでしょうか?
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2006-05-21 15:29
get だけだから同期は要らないですよね。と思いつつその根拠が分かりませんでした。もしかしたら get の際になにかフィールドの状態を変えているかもしれないし。もっとも、そんな変な実装だったら嫌ですけど。

と思って探したら、
http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/util/HashMap.html
の太字のところには、
引用:

この実装は同期化されません。複数のスレッドが同時にこのマップにアクセスし、それらのスレッドの少なくとも 1 つが構造的にマップを変更する場合には、外部で同期をとる必要があります。構造的な変更とは、1 つ以上のマッピングを追加または削除するオペレーションのことです。


と書いてあります。「それらのスレッドの少なくとも 1 つが」という条件があることから考えて、get だけなら同期は不要なはずです。

--
unibon {B73D0144-CD2A-11DA-8E06-0050DA15BC86}
ちょま吉
大ベテラン
会議室デビュー日: 2004/08/04
投稿数: 112
投稿日時: 2006-05-22 13:45
起動時のプロパティ読込時にGET、もしくはIteratorによる参照が無ければよいのですが。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2006-05-23 00:17
マルチスレッドのデザインパターンの1つで、
イミュータビリティを保障するという事があります。

Stringなどの不変オブジェクトが該当します。
Stringはマルチスレッドで安全に動作しますが、
特に同期を取っているわけではなく、状態が変化しないため、
どうやって利用されてもマルチスレッドで安全なのです。

値を参照するクラス向けには、生成したHashMapを直接参照させるのではなく、
Collections#unmodifiableMap等で、変更不可能なマップに変換してから参照させれば、
マルチスレッド間での同期は気にしなくてもいいでしょう。
1

スキルアップ/キャリアアップ(JOB@IT)