javaの「java.util.HashMap」はスレッドセーフではありません。
つまり、複数のスレッドから同時に値の変更が行われた場合には、どの状態の値が返ってくるか、保障されていないということになります。
アプリ内でシングルトンのオブジェクトとして値を保持しておくような場合、スレッドセーフな状態に制御するのはすこしコツが要ります。
今までは、synchronizedを使って自分で実装したり、Collections.synchronizedMapを使っていました。
しかし、jdk1.5からは「ConcurrentHashMap」という便利なクラスが使えるようになっています!
ConcurrentHashMapはjava.util.concurrentパッケージで提供されている、並行性をサポートする、スレッド・セーフなMapで、パフォーマンスもsynchronized等で実装したときより、向上しています。
ConcurrentHashMapの使い方
今までのHashMapと同じように使えます。putやget、初期化の方法も同じですね。
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class TestBatch {
public static void main(String args[]){
ConcurrentHashMap<String,String> map = new ConcurrentHashMap<String,String>();
map.put("キー1", "キー1の値");
map.put("キー2", "キー2の値");
map.put("キー2", "キー3の値");
if (map.containsKey("キー1")){
System.out.println("キー1=" + map.get("キー1"));
}else{
System.out.println("指定したキーは存在しません");
}
//拡張for文(for-each)でループ
for(Map.Entry<String, String> e : map.entrySet()) {
System.out.println(e.getKey() + " : " + e.getValue());
}
}
}
複数スレッドからアクセスされるような状況でMapを使う場合は、ConcurrentHashMapを使った実装を検討しましょう。