2012-05-14 4 views
7

ConcurrentHashMapのどこかで、マップオブジェクト全体がロックされておらず、代わりにマップの一部にロックが設定されていると読んでいます。ConcurrentHashMapのロック

ロックが写真にいつ登場するのですか?

マップを読み込んでいる間はロックはありませんが、更新中はロックのみが使用されていますか?

+3

この記事は役立ちます:http://www.ibm.com/developerworks/java/library/j-jtp08223/ – yegor256

+1

[javadoc](http://docs.oracle.com/javase/7/docs/) api/java/util/concurrent/ConcurrentHashMap.html)は実装を説明するのにかなり詳細です。 – trutheality

答えて

12

はい、ConcurrentHashMapは多数のロックを使用し、各ロックはハッシュの1つのセグメントを制御します。

特定のセグメントにデータを設定すると、そのセグメントのロックが取得されます。

データを取得するとき、揮発性の読み取りが使用されます。揮発性読取りがミスになる場合、読取りが成功したときの最後の試行のためにセグメントのロックが取得される。

+1

私は "揮発性の読み取り結果がミスであれば、成功した読み取りで最後の試行のためにセグメントのロックが取得された場合"を取得しませんでした。あなたは少し詳しく説明できますか? – Anand

+1

@anand JMMによれば、コンストラクタ内のフィールドの揮発性の書き込みは、オブジェクトの構築が完了した後にスレッドが見ることができ、他のスレッドから見える可能性があります(これは最終フィールドでは当てはまりません)。彼が言及しているロックは、その揮発性の書き込みと他の読み取りとの順序を保証する。注:これは起こることができましたが、Java 6で読むことはできませんでした。すべての混乱のためにJava 6を削除するという話がありました。 –

+2

そして、明確なコンストラクタを完成させるためには、バケットのエントリを参照するだけです。 –

5

スレッドセーフでありながら、できるだけロックを最小限に抑えます。

「マップの一部がロックされている」ことを説明するには、更新時に(キーのハッシュに基づいて)マップの「1/concurrencyLevel」のみがロックされていることを意味します。つまり、2つの更新が別々のバケットに影響を与えてもロックの競合を最小限に抑え、パフォーマンスを最大限に引き出すならば、安全に同時に2つの更新を実行できます。

さらに重要なことに、JDKの実装を信頼してください.JDKの実装の詳細について心配する必要はありません(リリース間で変更されることもあります)。むしろ、コードをと書いてください。

+0

Hashtableをリンクすると、ConcurrentHashMapを意味しますか?あなたの説明は、そうでなければ正しくありません。 Hashtableインスタンス全体は、変更または読み取りのために同期されます。 –

+0

@JohnVintありがとう。私は自分の答えを更新しました。 – Bohemian

+0

@truthealityありがとうございます。私は自分の答えを修正した。 – Bohemian

0

コンカレントハッシュマップ使用リエントラントロック機構。 ConcurrentHashMapはバケットの代わりにセグメントを使用し、新しいレコード取得の挿入ロックはセグメントの完全なリストではなくセグメントのみで取得されます。だからここでアイデアは、マルチレベルのロックが同じで取得することが明らかになります。

並行性レベルにexplicityが設定されていないため、ConcurrentHashMapは16のセグメントに分割されます。各セグメントは独立したHashMapとして機能します。

ConcurrentHashMapの読み取り操作に適用されるロックはありません。

関連する問題