Yige

Yige

Build

ConcurrentHashMapとHashtable

ConcurrentHashMap && Hashtable#

ConcurrentHashMap はどのようにスレッドセーフを実現しているのか?#

JDK1.5 での実装#

Segment(extends ReentrantLock)を使用して実現
セグメントロック技術を使用して、ConcurrentHashMap はロックをセグメントごとに保存し、各セグメントのデータにロック(segment)を割り当てます。あるスレッドが 1 つのロック(segment)を占有してそのセグメントのデータにアクセスしている間、他のセグメントのデータは他のスレッドによってもアクセス可能です。デフォルトで 16 個のセグメントが割り当てられ、デフォルトで Hashtable よりも 16 倍の効率が向上します。

JDK1.8 での実装#

CASsynchronizedを使用して並行安全を保証
JDK8 での実装もロック分離の考え方を採用しており、ロックをsegment(JDK1.5)よりも細かく分けています。ハッシュが衝突しなければ、並行してロックを取得することはありません。最初に無ロック操作CASでヘッドノードを挿入し、挿入に失敗した場合は、他のスレッドがヘッドノードを挿入したことを示し、再度ループして操作を行います(スピンロックに似ています)。ヘッドノードが既に存在する場合は、synchronizedでヘッドノードのロックを取得し、後続の操作を行います。性能はセグメント分割ロックよりもさらに向上しています。

Hashtable#

Hashtable もスレッドセーフなキーと値のペアのデータ構造です。

HashMap との比較:#

  1. Hashtable は JDK1.0 から存在し、HashMap は JDK1.2 で登場しました。
  2. Hashtable は Dictionary クラス(廃止)から継承され、HashMap は AbstractMap クラスから継承されています。
  3. Hashtable は Null キーも Null 値もサポートしていませんが、HashMap では null をキーとして使用でき、そのようなキーは 1 つだけ存在します;1 つまたは複数のキーに対応する値が null であることができます。
  4. Hashtable はスレッドセーフであり、すべてのメソッドに Synchronize メソッドが追加されていますが、HashMap はスレッドセーフではありません。
  5. Hashtable と HashMap はどちらも Iterator を使用していますが、歴史的な理由から Hashtable は Enumeration 方式も使用しています。
  6. Hashtable のデフォルトの初期サイズは 11 で、以降は毎回拡張されると容量は元の 2n+1 になります。HashMap のデフォルトの初期サイズは 16 で、以降は毎回拡張されると容量は元の 2 倍になります。
  7. ハッシュ値の計算方法が異なります:Hashtable はオブジェクトの hashCode を直接使用し、HashMap はさらに擾乱関数を使用して処理します。

Collections.synchronizedMap () との違い#

synchronizedMapは Collections のプライベート静的内部クラスであり、Collecitons.synchronizedMap(Map)メソッドを通じて synchronizedMap を Map オブジェクトにアップキャストすることができます。

比較分析:

  • Hashtable はすべてのメソッドに synchronized キーワードでロックをかけています。
  • Object 型の mutex 排他オブジェクトメンバーがあり、スレッドセーフなメソッドに対して synchronize キーワードで mutex にロックをかけています。
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。