ConcurrentHashMapの基礎となる構造の分析

jdk1.7のConcurrentHashMap

  • 基礎となるデータ構造: セグメント化された配列+リンクリストConcurrentHashMapは、Segmentデータ構造とHashEntryデータ構造で構成されています。セグメントはReentrantLockを実装しているため、Segmentは再入可能ロックであり、ロックの役割を果たします。HashEntryは、キーと値のペアのデータを格納するために使用されます。ConcurrentHashMapには、セグメントの配列が含まれています。セグメント配列の各要素にはHashEntry配列が含まれ、HashEntry配列の各要素はリンクリスト構造の要素です。セグメント配列の各要素は、HashEntry配列の単一の要素を保護します。HashEntry配列のデータを変更するときは、最初に対応するセグメント配列要素のロックを取得する必要があります。
    ここに画像の説明を挿入

  • スレッドセーフを実現する方法:最初にデータをストレージのセグメントに分割し、次にデータの各セグメントにロックを割り当てます。スレッドがデータのセグメントの1つにアクセスするためにロックを占有すると、他のセグメントのデータもアクセスできます。他のスレッドからアクセスできるため、同時アクセス率が向上します。

jdk1.8のConcurrentHashMap

  • 基盤となるデータ構造: ConcurrentHashMapは、セグメントロックをキャンセルし、CAS(Compare-and-Swap、compare and replace)を使用して同期し、同時実行の安全性を確保します。データ構造は、配列+リンクリスト/赤黒木であるHashMap1.8の構造に似ています(jdk1.6以降、バイアスロック、軽量ロック、スピンロック、ロック除去、ロック粗大化など、同期ロックに対して多くの最適化が行われました。)
  • スレッドセーフを実現する方法:
    ①jdk1.7では、ConcurrentHashMapはセグメント化されたロックを使用してバケット配列全体をセグメント化し(Segment)、各ロックはコンテナの一部のみをロックし、複数のスレッドがコンテナ内の異なるデータにアクセスしますセグメントデータはロックを生成しません競合し、同時アクセス率を上げます。
    jdk1.8時に、現在のリストの同期ロックのみ最初のノード、または赤黒木ので、長いハッシュが競合しないように、同時生産するだけでなく、N倍の効率を向上しないであろう。

jdk1.8のConcurrentHashMap(TreeBin:赤黒木ノード;ノード:リンクリストノード)
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/qq_47768542/article/details/109094878