同期されたデータ構造を必要とするコードを実装しようとしていました。HashTable
とを思いつきましたCollections.synchronized(HashMap)
。私はこれを必要としないでしょうConcurrentHashMap
。どっちがいいのかな?と悩みました。
PS : 私はこのオブジェクトの多くのゲッターを呼び出しますが、それらは同時にではありません。したがって、同時実行の問題についても問題ありません。
同期されたデータ構造を必要とするコードを実装しようとしていました。HashTable
とを思いつきましたCollections.synchronized(HashMap)
。私はこれを必要としないでしょうConcurrentHashMap
。どっちがいいのかな?と悩みました。
PS : 私はこのオブジェクトの多くのゲッターを呼び出しますが、それらは同時にではありません。したがって、同時実行の問題についても問題ありません。
ConcurrentHashMap
はるかにスケーラブルです: http://www.javamex.com/tutorials/concurrenthashmap_scalability.shtml
HashTable
Collections.synchronized(HashMap)
同じパフォーマンスを提供しますが、条件付きでスレッドセーフです (つまり、完全にスレッドセーフではありません)。
読み取り操作が多い場合は、読み取り/書き込みロックでラップすることをお勧めします。
public class MyHashMap<K, V> extends HashMap<K, V> {
private final ReadWriteLock lock = new ReentrantReadWriteLock();
@Override
public V put(K key, V value) {
final Lock w = lock.writeLock();
w.lock();
try {
return super.put(key, value);
} finally {
w.unlock();
}
}
@Override
public V get(Object key) {
final Lock r = lock.readLock();
r.lock();
try {
return super.get(key);
} finally {
r.unlock();
}
}
.... // the same approach distinguishing read and write operations
}
アップデート:
このオブジェクトの多くのゲッターを呼び出しますが、それらは同時にではありません
同期が不要であることを保証するものではありません。
何らかの理由でマップ全体のロックを取得する必要がない限り (可能性は低い)、ConcurrentHashMap
スケーラビリティが大幅に向上する方を選択する必要があります。
HashTable
および同期ラッパー ( Collections.synchronized(HashMap)
) は 1 つのロックを使用ConcurrentHashMap
しますが、マップはデフォルトで 16 のセグメントに分割され、それぞれが独自のロックを持ち、より優れた同時アクセスを提供します。
HashTable はスレッド セーフですが、コード全体がスレッド セーフになるとは限りません。HashTable にはパフォーマンス上の問題もあります。したがって、HashMap を使用する必要がありますが、すべてのスレッド セーフを自分で管理する必要があります。