10

Java Concurrecny in practiceという本を読んでいます。85 ページのセクション 5.2.1 では、ConcurrentHashMap とその利点について説明しています。ただし、一部では、本は次のように主張しています。

ConcurrentHashMap によって返される反復子は、一貫性が弱いです。これは、この反復子が同時変更を許容し、反復子が構築されたときに存在していた要素をトラバースし、反復子の構築後にコレクションへの変更を反映する可能性があることを意味します (ただし、保証はされません)。

ConcurrentHashMap が実際にはこれを実現していないため、並列プログラムでの同期の全体的なポイントは、スレッドが一貫した方法で共有リソースにアクセスできるようにすることであると私が理解している理由からです。それでは、なぜそれを使用するのですか?

4

3 に答える 3

18

ポイントは、必要のないときに同期を避けることです。場合によっては新しい要素が表示され、他の場合には表示されないことを気にしない場合は、反復中に他のスレッドがアイテムを追加するのを防ぐ、反復子が作成されたときに一貫したスナップショットを作成するよりConcurrentHashMap、 の反復子を使用する方が大幅に安価になる可能性があります。 .

そうです、同期と一貫したイテレータが必要な場合は、代替手段が必要になりますが、そうでない場合は、 が提供するより効率的なイテレータを利用できますConcurrentHashMap

于 2012-12-29T17:25:00.927 に答える
2

すべては、必要な一貫性の強さに依存します。強力なものが必要な場合-ミューテックスまたは他の操作のサブセットよりも、必要なものが提供されます。

ただし、より弱い要件が必要な場合もありますが、たとえばスループットを保証する必要があるため、ロックフリープロパティを指定する必要があります。一方、イテレータがまったく必要ない場合や、イテレータに対する制限がはるかに弱い場合があります。

したがって、必要なのがスレッド間で共有されるマップConcurrentHashMap(たとえば、劇場内の場所から予約者まで)だけであれば、必要なものが提供されます。ミューテックスの同期を回避するため、多くのスレッドが機能している場合は、はるかに高速になる可能性があります。一方、速度には代償が伴います。イテレータによって提供されるビューは、作成時の収集の状態に対応している必要はなく、後に作成された要素を見逃す可能性があります(一般にマルチプロセッサシステムのhappens-before関係では注意が必要です)。

編集:ジョン・ウェスレー王子が指摘したように、私はConcurrentSkipListMap見たり書いたりしながら考えました。ConcurrentHashMap。ロックフリーであることに関する部分(および保証されたスループットなど、そこから得られるすべてのもの)を除いて、ほとんどのポイントは依然として有効です。

于 2012-12-29T17:30:14.877 に答える
2

ConcurrentHashMap契約により、スレッドセーフであるはずです。ただし、スレッド間で一貫性があるとは想定されていません。

を繰り返し処理するConcurrentHashMapと、イテレータは要求した時点でハッシュ マップのコピーを取得し (このコピーはスレッド セーフな方法で作成されます)、そのコピーを繰り返し処理します。そして、はい、その copy を反復処理している間、一部のマップ エントリが削除されないことを保証するものは何もありません。しかし、そのような方法で削除されるマップ エントリは、 iterator にまだ存在します

于 2012-12-29T17:28:06.007 に答える