2016-11-16 4 views
4

emailIdtestUserIdsのリストを格納するインメモリHashMapを維持しています。ライタースレッドが1つだけの場合、java HashMap getsを同期させる必要がありますか

HashMap<Integer, String> testUsers = new HashMap<>() 

そしてtestUsersのリストへの追加/削除を読み込み、この地図上の操作を実行するだけで1バックグラウンドスレッドがあります。このマップに書き込むスレッドは1つだけなので、必ずしも同期マップにする必要はありません。

しかし、このマップから読み取るスレッドは複数あります。ライターが1人で複数の読者がある場合はConcurrentHashMapが必要ですか?

+1

1つのライタースレッドは、複数のリーダースレッドが読み込んでいるときに同時に書き込みを試みますか?ライターがなぜ反復しているのかを書くことができますか? – bradimus

+0

Writer ThreadはReader Threadsと同時に書き込みを行っています。読者はイテレータを使用しません。読者はmap.get(key)のみを使用します。 – robinkc

答えて

5

はい、ConcurrentHashMapを使用するか、外部でMapを同期させる必要があります。そうでない場合、書き込み側スレッドがMapを変更している間に、他のスレッドがMapを反復処理すると、ConcurrentModificationExceptionが返されます。 HashMapさんJavadocから

:この実装は同期化されていないことを

注意。 複数のスレッドが同時にハッシュマップにアクセスする場合、少なくとも1つのスレッドがマップを構造的に変更します外部と同期する必要があります。そのような変更が許可されていない場合、この例外は、オブジェクトの同時変更を検出したメソッドによってスローされてもよい

java.util.ConcurrentModificationExceptionが

:JavadocのConcurrentModificationException「sから

たとえば、1つのスレッドがコレクションを変更することは一般的に許可されていませんが、もう1つのスレッドはそれを反復しています。一般に、これらの状況では、反復の結果は未定義です。この動作が検出された場合、Iterator実装(JREによって提供されるすべての汎用コレクション実装の実装を含む)によっては、この例外がスローされる可能性があります。これを行うイテレータは、フェイル・ファースト・イテレータとして知られています。これらのイテレータは、将来不確定な時間に任意の非決定論的な動作を実行するリスクを回避するため、迅速かつきれいに機能しません。

+0

私はあなたの答えを調べていましたが、それは私の考えで1つの質問を喚起しました。一般に、HashMapでConcurrentHashMapを使用する方が良いでしょうか?質問の中で説明したのと同じ方法で、ほとんどのアプリケーションがマップを使用します。 –

+0

@NiranjanKumar 'ConcurrentHashMap'は同期のために' HashMap'より効率が悪いです。したがって、私は同期が必要なときにのみ使用します。 – Eran

+0

これは従来のReader-Writerの問題と似ています。はい、スレッドを安全にする必要があります。 –

0

はい、マルチスレッド環境で作業している場合は、同期を考慮する必要があります。それ以外の場合、予期しないデータが配信されます。

関連する問題