3

ConcurrentHashMapは、パフォーマンスを向上させるために複数のスレッドへの同時アクセスを提供できることを知っています。このクラス内では、セグメントが同期されます(私は正しいですか?)。質問は、この設計はスレッドの安全性を保証できるかということです。ConcurrentHashMapインスタンスの同じキーによってマップされたオブジェクトにアクセスして変更する30以上のスレッドがあるとしましょう。私の推測では、それらはまだそのために整列する必要がありますね。

「JavaConcurrencyinPractice」という本には、ConcurrentHashMapが同時読み取りと適切なレベルの同時書き込みを提供すると書かれているという私の記憶から。前述のシナリオで、私の推測が正しければ、コレクションの静的同期ラッパーAPIを使用するよりもパフォーマンスが向上することはありませんか?

明確にしてくれてありがとう、ジョン

4

5 に答える 5

6

変更中のオブジェクトへのすべてのアクセスを同期する必要があり、同じキーへのすべてのアクセスにまだ競合があると思われます。パフォーマンスの向上は、さまざまなキーへのアクセスでもたらされます。これはもちろん、より典型的なケースです。

于 2011-06-15T00:28:08.077 に答える
2

問題は、この設計でスレッドの安全性を保証できるかどうかです。

これにより、マップのスレッド セーフが保証されます。つまり、更新を同時に実行する複数のスレッドが存在する場合、マップ上のアクセスと更新は明確に定義された秩序だった動作をします。

キーまたは値オブジェクトのスレッド セーフが保証されます。また、より高いレベルの同期の形式は提供しません。

ConcurrentHashMap インスタンスで同じキーによってマップされたオブジェクトにアクセスして変更する 30 以上のスレッドがあるとします。

複数のスレッドが同じキーを使用しようとしている場合、それらの操作は必然的にある程度シリアル化されます。それは避けられません。

実際、ソース コードを簡単に見るとConcurrentHashMap、マップの特定のセグメントで競合が多すぎる場合は、従来のロックを使用するようにフォール バックするように見えます。また、複数のスレッドが同じキーに同時にアクセスして更新しようとすると、ロックがトリガーされます。

于 2011-06-15T01:24:28.433 に答える
2

同時実行性について言えることは、ConcurrentMapマップ自体への変更がアトミックに行われ、読み取りの前に書き込みが行われることだけです (これは、マップからの参照を安全に公開できるため重要です。

安全な公開とは、マップから取得されたすべての (変更可能な) オブジェクトが、マップに配置されるにすべての書き込みと共に表示されることを意味します。ただし、それを取得した後に行われた変更を公開するのには役立ちません。

ただし、複数の関係者によって変更されている可変オブジェクトがある場合、同時実行性とスレッド セーフは一般的に推論して修正するのが困難です。通常、それを正しく行うにはロックする必要があります。ConcurrentMap多くの場合、より良いアプローチは、条件付きの putIfAbsent/replace メソッドと組み合わせて不変オブジェクトを使用し、その方法でアルゴリズムを線形化することです。このロックフリースタイルは、推論しやすい傾向があります。

于 2011-06-15T00:42:26.937 に答える
1

最初に、スレッド セーフ ツールはそれ自体でのスレッド セーフな使用を保証しないことを覚えておいてください。

if(!map.contains(k))map.put(k,v);たとえば、 putIfAbsentの構造はスレッドセーフではありません

各値のアクセス/変更は、個別にスレッドセーフにする必要があります

于 2011-06-15T00:29:59.003 に答える
0

読み取りは同じキーであっても並行して行われるため、一般的なアプリケーションのパフォーマンスは向上します。

于 2011-06-15T01:25:31.097 に答える