2013-04-12 7 views
8

を行うとき、私はチュートリアルを以下だと、それは基本的にマルチスレッド環境でハッシュマップのサイズを変更する場合に発生する競合状態の原因について説明します。同じ2つのスレッド場合、JavaではHashMapのリサイズ

HashMapのサイズを変更する必要があり、サイズを変更しようとしています。 JavaのHashMapのサイズ変更のプロセスでは、リンクされたリストに格納されているバケットの要素は、新しいバケットへの移行中に順番に逆順になります。java HashMapは新しい要素を末尾に追加するのではなく、テールトラバースを避ける。競合状態が発生した場合、あなたは無限ループ

で終わるだろう、私はこれを読んだ後に二つの質問があります。

  1. をなぜ各バケットのリンクリストは、順番に逆転されていますか?
  2. 競合状態があるかもしれませんが、無限ループがどのように起こっているのか分かりません。それは、一方のスレッドが要素の先頭を末尾に追加し、他方のスレッドは逆の順序でそれを行うためですか?

これを明確にするのを手伝ってください、非常に感謝します!

+1

は、私はあなたの質問への答えを知らない - 私はちょうどあなたがスレッドセーフ[ConcurrentHashMapの](使用することをお勧めしたいですhttp://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ConcurrentHashMap.html)を参照してください。 –

+0

'HashMap'はスレッドセーフではありません。マルチスレッド環境で使用することは悪い考えです。別の方法で競争条件を取得します。 – gaborsch

答えて

2

実際には、再ハッシングに関連する競合状態が少なくとも1つあります。このコードの断片を見てください(それは日JDK7からです):

boolean oldAltHashing = this.useAltHashing; 
this.useAltHashing |= sun.misc.VM.isBooted() && (this.newCapacity >= Holder.ALTERNATIVE_HASHING_THRESHOLD); 
boolean rehash = oldAltHashing^this.useAltHashing; 
transfer(newTable, rehash); 
this.table = newTable; 

ここ(のは、T1は、すでにthis.useAltHashingの値を変更したと仮定しましょう)スレッドT1はrehash = trueで終わる可能性があり、スレッドT2はrehash = falseで終了。

ここで、どちらのスレッドがthis.tableを書き込むかを推測してください。どちらもできません。だから、一貫した内部状態を取得するかどうかは運の問題です。

とにかく、私のコメントで設計したので、マルチスレッド環境ではHashMapを使用しないでください。うまくいかないだろう。これのために、または他の理由のために。上記はちょうど1つの例だったあなたは契約に反対しようとするべきではありません。

0

この例が有効かどうかわかりません。明らかに、それは実装固有のものです。私はそれも大きな写真が欠けていると思う。

HashMapさんcontractクリアな状態(強調彼らを):

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

あなたが契約を破る場合は、すべての賭けオフです。この地図は自由に任意の、不特定の方法で爆破することができます。

9

あなたの最初の質問に対する答えは、引用符で囲まれたテキストである:

「JavaのHashMapのは、末尾に新しい要素を追加していないため、代わりにそれは尾のトラバースを避けるために先頭に新しい要素を追加」

HashMapが挿入順にそれらを格納する場合は、各挿入時にリストを走査するか、リストの末尾に余分なポインタを格納して維持する必要があります。バケット内の要素を挿入順に格納しても、何のメリットもありません(少なくとも私は考えることはできません)。

あなたの2番目の質問への答えはここに依存しています:

http://mailinator.blogspot.hu/2009/06/beautiful-race-condition.html

+2

+1のリンク – Songo