Collections.synchronizedMapを使用せずに、リンクされたハッシュマップの同期を外部で実装するための最良の方法は何ですか
Collections.synchronizedMapを使用すると、データ構造全体がロックされるため、パフォーマンスに大きな影響があります。
データ構造の必要な部分のみをロックするための最良の方法は何ですか。たとえば、スレッドがキー(K1)にアクセスしている場合、データ構造のKey(K1)とValue(v1)の部分のみをロックする必要があります
Collections.synchronizedMapを使用せずに、リンクされたハッシュマップの同期を外部で実装するための最良の方法は何ですか
Collections.synchronizedMapを使用すると、データ構造全体がロックされるため、パフォーマンスに大きな影響があります。
データ構造の必要な部分のみをロックするための最良の方法は何ですか。たとえば、スレッドがキー(K1)にアクセスしている場合、データ構造のKey(K1)とValue(v1)の部分のみをロックする必要があります
組み込みのJava実装から、きめ細かいロックのFIFOエビクション同時マップを取得することはできません。
GuavaCache
またはオープンソースConcurrentLinkedHashMap
プロジェクトをチェックしてください。
マップからの値だけで、後続の操作を同期したいと思うかもしれません。
Object value = map.get(key);
synchronized(value) {
doSomethingWith(value);
}
マップから取得した値に同期することは、それらを同時に共有およびアクセスできるため、理にかなっています。上に投稿した例は、必要なことを実行するはずです。それで十分なはずです。
ちなみに、2つのネストされた同期ブロックを実行してキーで同期することもできます。
synchronized(key) {
Object value = map.get(key);
synchronized(value) {
doSomethingWith(value);
}
}
キーは、(通常は)オブジェクトにアクセスするために(ハッシュによって)使用されます。キーはハッシュ値によって照合されるため、キーを介して同期することは私にはまったく意味がありません。
ConcurrentHashMap
または、に欠けているものをサブクラス化して追加することもできますLinkedHashMap
。
Louis Wassermanの提案は、多くの便利な機能を提供するため、おそらく最良です。ただし、マップ全体をロックしたとしても、それをボトルネックにするのは非常に困難である必要があります(たとえば、コードは主にマップ上で読み取り/書き込みを行っています)。Guavaの追加機能が必要ない場合はCache
、同期されたマップの方が簡単で優れている可能性があります。ReadWriteLock
ほとんどの場合、マップから読み取る場合は、を使用することもできます。
が必要ない場合は、パッケージLinkedHaspMap
のを使用してください。ConcurrentHashMap
java.util.concurrent
速度とスレッドセーフの両方のために特別に設計されています。スレッドセーフを実現するために、可能な限り最小限のロックを使用します。
最良のオプションはを使用することjava.util.concurrent.ConcurrentHashMap
です。
マップ関数の呼び出しによって内部的にアクセスされる共有データ構造を制御できないため、zourMapの一部のみを外部でロックする方法がわかりません。
HashMapまたはLinkedHashMapに挿入すると、バケットのサイズと数の比率が高くなるため、再ハッシュが発生する可能性があります。2つ以上のスレッドを同時に再ハッシュするのは大変なことです。
getのみを実行している場合でも、別のスレッドが同じバケットからエントリを削除している可能性があるため、自分の下で変更されているリンクリストをスキャンしています。また、メインのリンクリストに同時に2つ以上のスレッドを追加することもできます。
リンクなしで実行できる場合は、すでに提案されているように、java.util.concurrent.ConcurrentHashMapを使用してください。