ConcurrentHashMapと同期HashMap


148

ラッパークラスを使用しての違いは何であるSynchronizedMap上、HashMapとはConcurrentHashMap

それHashMapを反復しながら(ConcurrentHashMap)を変更できるだけですか?

回答:


120

同期済みHashMap

  1. 各メソッドは、オブジェクトレベルのロックを使用して同期されます。したがって、synchMapのgetおよびputメソッドはロックを取得します。

  2. コレクション全体をロックすると、パフォーマンスのオーバーヘッドになります。1つのスレッドがロックを保持している間、他のスレッドはコレクションを使用できません。

ConcurrentHashMap JDK 5で導入されました。

  1. オブジェクトレベルでのロックはありません。ロックはより細かい単位で行われます。の場合ConcurrentHashMap、ロックはハッシュマップバケットレベルにある可能性があります。

  2. 下位レベルのロックの効果は、同期されたコレクションでは不可能である、リーダーとライターを同時に使用できることです。これにより、スケーラビリティが大幅に向上します。

  3. ConcurrentHashMapConcurrentModificationException別のスレッドがそれを繰り返している間に、あるスレッドがそれを変更しようとした場合、はスローされません。

この記事Java 7:HashMapとConcurrentHashMap は非常によく読まれています。強くお勧めします。


7
だから、間に別の何かHashtableとはSynchronized HashMap
roottraveller 2017

1
ConcurrentHashMapとSynchronized HashMapのどちらをお勧めしますか?
Blunderchips 2017年

2
ConcurrentHashMapsize()結果が古くなる可能性があることは言及する価値があります。size()「Java Concurrency in Practice」の本によれば、正確なカウントの代わりに近似値を返すことが許可されています。したがって、この方法は慎重に使用する必要があります。
Andrii Lisun

1
ハッシュテーブルと同期HashMapのため@roottraveller stackoverflow.com/questions/8875680/...
ナレンドラJaggi

89

短い答え:

どちらのマップも、Mapインターフェースのスレッドセーフな実装です。ConcurrentHashMap高い並行性が期待される場合のスループットを高めるために実装されています。

ブライアンゲッツの背後にあるアイデアに関する記事ConcurrentHashMapは、非常によく読まれています。強くお勧めします。


1
これは何ですか?HashMap:この実装は、マップへの偶発的な非同期アクセスを防ぐために同期されていないことに注意してください: Map m = Collections.synchronizedMap(new HashMap(...)); docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
X-HuMan

5
「ブライアンゲッツの記事...はとても良い本です。」-さらに、彼の「Java Concurrency in Practice」の本もそうです。
Alex Fedulov、2015

31

ConcurrentHashMapマップ全体を同期せずにスレッドセーフです。書き込みがロックで行われている間、読み取りは非常に高速に行われます。


18

ConcurrentHashMapとsynchronisedHashmapの両方を使用することでスレッドセーフを実現できます。しかし、それらのアーキテクチャを見ると、多くの違いがあります。

  1. synchronisedHashmap

オブジェクトレベルでロックを維持します。したがって、put / getなどの操作を実行する場合は、最初にロックを取得する必要があります。同時に、他のスレッドは操作を実行できません。したがって、一度に1つのスレッドのみがこれを操作できます。したがって、ここで待機時間が増加します。ConcurrentHashMapと比較すると、パフォーマンスは比較的低いと言えます。

  1. ConcurrentHashMap

セグメントレベルでロックを維持します。これには16のセグメントがあり、並行性レベルはデフォルトで16に維持されます。したがって、一度に16個のスレッドがConcurrentHashMapを操作できます。さらに、読み取り操作はロックを必要としません。そのため、任意の数のスレッドがget操作を実行できます。

thread1がセグメント2でput操作を実行し、thread2がセグメント4でput操作を実行したい場合は、ここで許可されます。つまり、16個のスレッドが一度にConcurrentHashMapに対して更新(書き込み/削除)操作を実行できます。

待ち時間が少なくなるように。したがって、パフォーマンスはsynchronisedHashmapよりも比較的優れています。


とても良い説明ありがとうございました
amoljdv06

11

どちらもHashMapの同期バージョンであり、コア機能と内部構造が異なります。

ConcurrentHashMapは、概念的には独立したHashMapとして表示できる内部セグメントで構成されています。このようなセグメントはすべて、同時実行が多い実行では、個別のスレッドによってロックできます。そのため、複数のスレッドがConcurrentHashMapからキーと値のペアを取得/出力でき、互いをブロック/待機する必要はありません。これは、より高いスループットのために実装されています。

一方

Collections.synchronizedMap()、HashMapの同期バージョンを取得し、ブロック方式でアクセスします。つまり、複数のスレッドが同時にsynchronizedMapにアクセスしようとした場合、それらは同期された方法で一度に1つずつキーと値のペアを取得/出力することができます。


7

ConcurrentHashMaplock stripping、より高度な共有アクセスを可能にするために知られている、よりきめ細かいロックメカニズムを使用します。これにより、並行性スケーラビリティが向上します。

またのために返されるイテレータは、ConcurrentHashMapある弱一貫性の代わりに、高速な手法失敗同期のHashMapで使用します。


3

SynchronizedMapオブジェクトのロックを保持するメソッドConcurrentHashMapですが、コンテンツのバケットにロックを保持する「ロックストライピング」の概念があります。したがって、スケーラビリティとパフォーマンスが向上しました。


2

ConcurrentHashMap:

1)どちらのマップも、Mapインターフェースのスレッドセーフな実装です。

2)ConcurrentHashMapは、高い並行性が期待される場合のスループットを高めるために実装されます。

3)オブジェクトレベルでのロックはありません。

同期ハッシュマップ:

1)各メソッドは、オブジェクトレベルのロックを使用して同期されます。


1

ConcurrentHashMapは、データへの同時アクセスを可能にします。マップ全体がセグメントに分割されています。

読み取り操作、つまり get(Object key)セグメントレベルでも同期されません。

しかし、書き込み操作、すなわち。remove(Object key), get(Object key)セグメントレベルでロックを取得します。マップ全体の一部のみがロックされますが、他のスレッドは、ロックされたセグメントを除くさまざまなセグメントから値を読み取ることができます。

一方、SynchronizedMapでは、オブジェクトレベルでロックを取得します。すべてのスレッドは、操作(読み取り/書き込み)に関係なく、現在のスレッドを待機する必要があります。


1

ConcurrentHashMapとSynchronized HashMapの簡単なパフォーマンステスト 。テストフローはput1つのスレッドで呼び出しgetMap同時に3 つのスレッドで呼び出しています。@trshivが言ったように、ConcurrentHashMapは、ロックなしの読み取り操作に対してより高いスループットと速度を持っています。その結果、操作時間が終了すると10^7、ConcurrentHashMapは2xSynchronized HashMapよりも高速になります。


1

SynchronizedMapConcurrentHashMapスレッドセーフクラスであり、マルチスレッドアプリケーションで使用できます。これらの主な違いは、スレッドセーフを実現する方法に関するものです。

SynchronizedMapMapインスタンス全体をロックし、ConcurrentHashMapMapインスタンスを複数のセグメントに分割し、それらをロックします。

ここに画像の説明を入力してください

ここに画像の説明を入力してください


0

Javaドキュメントのとおり

HashtableとCollections.synchronizedMap(new HashMap())は同期されます。しかし、ConcurrentHashMapは「並行」です。

並行コレクションはスレッドセーフですが、単一の排他ロックによって制御されません。

ConcurrentHashMapの特定のケースでは、任意の数の同時読み取りと調整可能な数の同時書き込みを安全に許可します。「同期」クラスは、スケーラビリティーが低下する代わりに、単一のロックを介してコレクションへのすべてのアクセスを防止する必要がある場合に役立ちます。

複数のスレッドが共通のコレクションにアクセスすることが予想される他のケースでは、通常は「並行」バージョンが推奨されます。また、同期されていないコレクションは、コレクションが共有されていない場合、または他のロックを保持している場合にのみアクセスできる場合に適しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.