2012-01-05 12 views
7

私は2つのクラス間の違いを探していたし、この時点では、このブログが源であるとの回答の多くに思い付いた: http://javarevisited.blogspot.com/2010/10/difference-between-hashmap-and.htmlHashMapのイテレータがフェイル・ファーストで、HashTableの列挙子が正確ではないことは何ですか?

しかし、私は完全にそれを得ることはありません。 誰かがこれを詳しく説明できますか?おそらく一例ですか?

ありがとうございました!

答えて

12

フェイル・ファーストとは、反復処理中にコンテンツを変更しようとすると失敗し、ConcurrentModificationExceptionをスローします。ハッシュテーブルの列挙については

Set keys = hashMap.keySet(); 
for (Object key : keys) { 
    hashMap.put(someObject, someValue); //it will throw the ConcurrentModificationException here 
} 

Enumeration keys = hashTable.keys(); 
while (keys.hasMoreElements()) { 
      hashTable.put(someKey, someValue); //this is ok 
    } 
+3

Hastableのイテレータはフェイル・ファーストです。その列挙はそうではありません。 –

+0

あなたは正しいです!ありがとう! – evanwong

3

を呼び出すときに、イテレータが作成されてから瞬間next()が呼び出されたときに変更が加えられると、すぐにConcurrentModificationExceptionがスローされます。これはフェイル・ファーストを意味します。

Hashtableから返された列挙型にはこの動作がありません。彼らはあなたが何をやっているのかを前提としており、AFAIKの動作は、その列挙の1つを使ってマップを反復しながら修正すると、未定義です。

3

最も良い方法は、各クラスのOpen JDK実装で実装されているように、おそらく各クラスのソースを調べることです。そういう意味では、あなたは馬の口からまっすぐに答えを得ることができます:-)

この意味での「フェイル・ファスト」は、基本的には、HashMap上のIteratorは例外をスローします別のスレッドがターゲットのHashMapを変更したことを検出します。ソース内でHashMapを調べると、期待される変更の数をカウンタでチェックするだけで完了します。修正カウントが期待される反復子と異なる場合、それは最後のチェックの後に他の誰かが来て、HashMapで混乱しているので、反復子はConcurrentModificationExceptionをスローします。

"非フェイル・ファースト"イテレータは、チェックするのが面倒ではなく、基盤となるデータ構造のビジネスに喜んで従います。したがって、おそらく後でエラーに遭遇することと引き換えに、ある程度の柔軟性(おそらく疑わしい柔軟性)を得ることができます。すなわち、もはや存在しない値にアクセスしようと試みる。

すべてのfail-fastの戦略と同様に、エラーが早期に検出されると、回復またはデバッグが容易になるという考えがあります。

+3

だけではなく、別のスレッド。同じスレッド内であっても、反復処理中にマップを変更すると、ConcurrentModificationがスローされます(イテレータ自体を使用してマップを変更する場合を除く) –

+0

非常に真です!ときどき混乱した間違いを私自身はやっていました:-) –

関連する問題