私はJavaの同時実行性に関するオラクルの公式ドキュメントを読んでいて、によって返されるCollection
の違いは何だろうと思っていました。
_public static <T> Collection<T> synchronizedCollection(Collection<T> c);
_
そして例えばを使用して
ConcurrentHashMap
。私はHashMap
でsynchronizedCollection(Collection<T> c)
を使用すると仮定しています。一般に、同期されたコレクションは基本的にHashMap
の単なるデコレータであることがわかっているので、ConcurrentHashMap
の内部には異なるものがあることは明らかです。これらの実装の詳細に関する情報はありますか?
編集:ソースコードが公開されていることに気付きました:ConcurrentHashMap.Java
ConcurrentHashMapのソース を読みます。詳細はかなり複雑です。要するに
ConcurrentHashMap
はJava.util.HashTable
クラスに非常に似ていますが、ConcurrentHashMap
はHashTable
やsynchronizedMap
よりも優れた並行性を提供します。 ConcurrentHashMap
は、マップの読み取り中にマップをロックしません。また、ConcurrentHashMap
は、書き込み時にMap
全体をロックしません。内部的に書き込まれるMap
の部分のみをロックします。
もう1つの違いは、反復中にConcurrentModificationException
が変更されても、ConcurrentHashMapはConcurrentHashMap
をスローしないことです。 Iterator
は複数のスレッドで使用するようには設計されていませんが、synchronizedMap
はConcurrentModificationException
をスローする場合があります
これは私がそれを理解するのを助けた記事です なぜConcurrentHashMapはHashtableよりも優れており、HashMapと同じくらい良い
Hashtableはエントリへの同時アクセスを提供しますが、小さな警告があり、あらゆる種類の操作を実行するためにマップ全体がロックされます。このオーバーヘッドは通常の負荷のWebアプリケーションでは無視できますが、高負荷の場合、正当な理由がないため応答時間が遅くなり、サーバーの過負荷につながる可能性があります。
これがConcurrentHashMapのステップインです。Hashtableとほぼ同等のパフォーマンスでHashtableのすべての機能を提供します。 ConcurrentHashMapは、非常に単純なメカニズムでこれを実現します。コレクションは、マップ全体のロックの代わりに、デフォルトで16個のロックのリストを保持します。各リストは、マップの単一のバケットを保護(またはロック)するために使用されます。つまり、16個のスレッドが一度にコレクションを変更できることを意味します(それらがすべて異なるバケットで動作している限り)。実際、このコレクションによって実行される、マップ全体をロックする操作はありません。コレクションの同時実行レベル、つまりブロックせずに同時にコレクションを変更できるスレッドの数を増やすことができます。ただし、数値が大きいほど、このロックのリストを維持するオーバーヘッドが大きくなります。
Hashtable
の「スケーラビリティの問題」は、Collections.synchronizedMap(Map)
でもまったく同じように存在します。非常に単純な同期を使用します。つまり、同時に1つのスレッドのみがマップにアクセスできます。
これは、単純な挿入とルックアップがある場合はそれほど問題ではありませんが(非常に集中的に行う場合を除き)、マップ全体を反復処理する必要がある場合は大きな問題になります。 1つのスレッドがそれを行い、他のすべてのスレッドは何かを挿入または検索する場合に待機する必要があります。
ConcurrentHashMap
は非常に高度な技術を使用して同期の必要性を減らし、同期なしで複数のスレッドによる並列読み取りアクセスを許可します。さらに重要なことは、同期を必要とせず、インターレーション中にMapを変更できるイテレーターを提供します(ただし、反復中に挿入された要素が返されるかどうかは保証されません)。
synchronizedCollection()によって返されるオブジェクトは、すべてのメソッドがthisで同期されるオブジェクトであるため、このようなラッパーでのすべての同時操作はシリアル化されます。 ConcurrentHashMapは、競合を可能な限り低く抑えるように最適化されたきめの細かいロックを備えた真のコンカレントコンテナです。ソースコードを見ると、中身がわかります。
ConcurrentHashMapは、並行性を提供するConcurrentMapを実装します。深い内部のイテレータは、同期を維持する一度に1つのスレッドのみが使用するように設計されています。このマップは、並行処理で広く使用されています。