2

ConcurrentHashMap にはセグメンテーションの概念があります。2 つのスレッドが ConcurrentHashMap にアクセスしようとすると、2 つのブロックに分割され、ブロックのデフォルト サイズは 16 になります。

ここで、ConcurrentHashMap に 2 つの要素しかなく、2 つの異なるスレッドが来て、thread1 が最初の値を変更しようとし、thread2 が 2 番目の値を変更しようとするシナリオを想定します。この場合、ConcurrentHashMap がセグメンテーションに使用されるかどうか?

別のシナリオでは、両方のスレッドが同じ値を変更しようとしていますが、ConcurrentHashMap はこの状況をどのように処理しますか? ロック機構を使用することによって、または何か他のものがありますか?

4

3 に答える 3

4

ConcurrentHashMap には複数のバケットがあります。キーは、ハッシュ値に基づいてバケットの 1 つにマップされます。値を追加または取得すると、そのキーに関連付けられたバケットがロックされます。

最初の質問の場合、2 つの可能性があります。両方のキーが同じバケットに存在するか、別のバケットに存在するかです。最初のケースでは、一度に 1 つのスレッドしか動作できません。最初にロックを取得したスレッドがロックを取得して動作し、2 番目のスレッドが順番を待ちます。キーが異なるバケットにある 2 番目のケースでは、それぞれが独立したロックを取得し、同時に作業を行います。

2 番目の質問では、ロックされるのはバケットであり、他には何もありません。2 つのスレッドが同じキーに対して 2 つの値を格納しようとすると、ConcurrentHashMap は 2 つの値のいずれかがキーに関連付けられることを約束します。つまり、スレッド A が実行map.put("Answers",2);され、スレッド B が実行map.put("Answers",10);された場合、ConcurrentHashMap はマップが有効であり、2または10for"Answers"のいずれかを含むことを保証しますが、それら 2 つのうちどちらであるかについては約束しません。

于 2013-04-09T18:25:40.100 に答える
3

putCHM は、これらの操作 (例: 、putIfAbsentなど) が重複しないことを保証します。はい、それはロックによって行われます。CHM の各セグメントには、そのセグメントを変更するたびに取得される独自のロックがあります。

(参考までに、@Affeが指摘したように、の値の内容ConcurrentHashMapを変更している場合、CHMはそのスレッドを安全にするために何もしません-できません。)

于 2013-04-09T18:15:37.127 に答える