52

私はJavaでの並行性に関する公式のOracleドキュメントを読んでいてCollection

public static <T> Collection<T> synchronizedCollection(Collection<T> c);

たとえば、

ConcurrentHashMapsynchronizedCollection(Collection<T> c)で使用することを前提としていHashMapます。一般に、同期されたコレクションは基本的に私のデコレータにすぎないことを知っているので、aの内部に何か異なるものがHashMapあることは明らかです。ConcurrentHashMapそれらの実装の詳細についていくつかの情報がありますか?

編集:ソースコードが公開されていることに気づきました: ConcurrentHashMap.java

4

6 に答える 6

50

ConcurrentHashMapのソースは詳細がかなり複雑なので、読みます。要するにそれは持っています

  • 独立してロックできる複数のパーティション。(デフォルトでは16)
  • 同期する代わりに、スレッドセーフのために同時ロック操作を使用する。
  • スレッドセーフなイテレータがあります。synchronizedCollectionのイテレータはスレッドセーフではありません。
  • 内部ロックを公開しません。同期コレクションは行います。
于 2012-08-03T09:39:40.243 に答える
27

はクラスConcurrentHashMapと非常に似ていますが、またはよりも優れた同時実行性を提供する点が異なります。あなたがそれから読んでいる間、地図をロックしません。さらに、書き込み時に全体をロックしません。書き込まれている部分のみを内部的にロックします。java.util.HashTableConcurrentHashMapHashTablesynchronizedMapConcurrentHashMapConcurrentHashMapMapMap

もう1つの違いは、反復中に変更されConcurrentModificationExceptionた場合、 ConcurrentHashMapがスローされないことです。ただし、複数のスレッドで使用するようには設計されていませんが、ConcurrentHashMapスローされる可能性がありますIteratorsynchronizedMapConcurrentModificationException

于 2012-08-03T09:38:26.160 に答える
18

これは、 ConcurrentHashMapがHashtableよりも優れており、HashMapと同じくらい優れている理由を理解するのに役立った記事です。

Hashtableは、エントリへの同時アクセスを提供しますが、小さな注意点がありますが、マップ全体がロックされて、あらゆる種類の操作を実行できます。このオーバーヘッドは、通常の負荷がかかっているWebアプリケーションでは無視できますが、負荷が高いと、応答時間が遅くなり、正当な理由もなくサーバーに過大な負担がかかる可能性があります。

これがConcurrentHashMapのステップインです。これらはHashtableのすべての機能を提供し、HashMapとほぼ同等のパフォーマンスを発揮します。ConcurrentHashMapは、非常に単純なメカニズムによってこれを実現します。コレクションは、マップ全体のロックの代わりに、デフォルトで16個のロックのリストを維持します。各ロックは、マップの1つのバケットを保護(またはロックオン)するために使用されます。これは事実上、16個のスレッドが一度にコレクションを変更できることを意味します(すべてが異なるバケットで動作している限り)。実際、マップ全体をロックするこのコレクションによって実行される操作はありません。コレクションの同時実行レベル、つまりブロックせずに同時に変更できるスレッドの数を増やすことができます。ただし、数値が大きいほど、このロックのリストを維持するためのオーバーヘッドが大きくなります。

于 2012-08-03T10:00:21.787 に答える
5

の「スケーラビリティの問題」Hashtableは、とまったく同じように存在しますCollections.synchronizedMap(Map)。つまり、非常に単純な同期を使用します。つまり、同時にマップにアクセスできるのは1つのスレッドだけです。

これは、単純な挿入とルックアップがある場合(非常に集中的に行わない限り)はそれほど問題にはなりませんが、マップ全体を反復処理する必要がある場合は大きな問題になります。これは、大きなマップの場合は長い時間がかかる可能性があります。 1つのスレッドがそれを行い、他のすべてのスレッドは、何かを挿入またはルックアップする場合に待機する必要があります。

ConcurrentHashMap非常に高度な手法を使用して、同期の必要性を減らし、同期なしで複数のスレッドによる並列読み取りアクセスを可能にします。さらに重要なことに、同期を必要とせず、相​​互作用中にマップを変更できるイテレーターを提供します(ただし、反復中に挿入された要素が返されるかどうか)。

于 2013-03-01T09:05:33.440 に答える
4

synchronizedCollection()によって返されるのは、このオブジェクトですべてのメソッドが同期されるオブジェクトであるため、このようなラッパーでのすべての同時操作はシリアル化されます。ConcurrentHashMapは、競合を可能な限り低く抑えるように最適化された、きめ細かいロックを備えた真の並行コンテナーです。ソースコードを見てみると、その中身がわかります。

于 2012-08-03T09:38:25.260 に答える
0

ConcurrentHashMapは、同時実行性を提供するConcurrentMapを実装します。内部的には、そのイテレータは、同期を維持する一度に1つのスレッドのみが使用するように設計されています。このマップは、並行性で広く使用されています。

于 2018-12-04T06:18:55.130 に答える