3

同期されていないものへの同時更新HashMapは、明らかにライブロックやその他のデータ破損を引き起こす可能性があります。これを回避するには、並行バージョンを使用するか、同期メカニズムを実装する必要があります。

HashMap.get()への同時呼び出しは、再ハッシュのように HashMap の状態を変更できますか?

アップデート:

一部のコメンターは、データ構造の動作をつまらないものにするという理論的な喜びに加えて、質問の実際的な側面について疑問に思いました。

get()の状態を変更しない場合HashMap(および別の理由でライブロックを発生させることができない場合)、1 つのスレッドが事前に HashMap を作成し、多数のスレッドが HashMap から同時に読み取ることができます。同時読み取りが安全でない場合はConcurrentHashMap、タイプに関係なく、すべてのマルチスレッド アクセスが必要です。

4

4 に答える 4

4

Javaドキュメントから:

複数のスレッドが同時にハッシュ マップにアクセスし、少なくとも 1 つのスレッドがマップを構造的に変更する場合は、外部で同期する必要があります。(構造変更とは、1 つ以上のマッピングを追加または削除する操作です。インスタンスに既に含まれているキーに関連付けられた値を変更するだけでは、構造変更にはなりません。)

これは、同時実行get()が問題なく、状態の変化を引き起こさないことを意味します。

さらに、いつでもソースを参照して、ビルド方法の詳細を確認できます。

于 2012-11-14T07:48:04.007 に答える
1

Javadoc は一般に、マップの構造変更と見なされるものを定義します。HashMap はget、構造変更を引き起こす操作ではないと述べています。

ただし、他のマップの実装では動作が異なります。たとえば、LinkedHashMapはアクセス順序を使用できます。この場合getは構造的な変更です。

アクセス順のリンクされたハッシュ マップでは、get を使用してマップをクエリするだけで、構造が変更されます。

于 2012-11-14T07:45:24.907 に答える
0

HashMap.get()(インターフェイスの特定の実装である)内部で何が起こっているかを知りたい場合はMap、実装のコードを読むことができます。

しかし、すべての目的のために、関数がどのように実装され、何をするかを気にするべきではありません! 唯一重要なことは、関数がその契約 (API + クラス/関数の javadoc) に到達することです。実装は将来変更される可能性があるため、それに依存するのは悪い習慣です。

于 2012-11-14T07:45:44.070 に答える
0

おっしゃる通り、通話だけでget()は問題ないでしょう。ただし、同期されていない更新が同時に発生すると、確実にそうなる可能性があります。methodでは、一致するものが見つかるまで、メンバーのメソッドget()を呼び出すだけです。hashcode()この場合、更新は行われません。

于 2012-11-14T07:51:28.427 に答える