2016-08-26 5 views
1

以下はコードですが、subiter.next()の呼び出しでConcurrentModificationExceptionが呼び出されていますが、基になるコレクションとそのスレッドを1つのスレッドとして実行しているわけではありません。このコードがConcurrentModificationExceptionをスローしているのはなぜですか?

Tree tree=partition.getTreeofThisPartition(); 
Set<DzExpressionHostTupel> oldSubtupels=tree.getSubscribers(); 
Iterator<DzExpressionHostTupel> subiter=oldSubtupels.iterator();   
while (subiter.hasNext()){ 
    DzExpressionHostTupel subtupel=subiter.next(); 
    tree.removeSubscriber(subtupel); 
} 
+1

可能性のある複製http://stackoverflow.com/questions/1655362/concurrentmodificationexception-despite-using-synchronized – NageN

+0

'tree.removeSubscriber(subtupel)'の代わりに 'subiter.remove()'メソッドを使用する必要があります。 – NageN

+0

以前に追加された既存のツリーから要素を削除する必要があります。iterator.remove()はそれを行いません。 –

答えて

5

あなたがhttps://docs.oracle.com/javase/7/docs/api/java/util/ConcurrentModificationException.htmlを読めば、それは言う:たとえば

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

この例外は、必ずしもオブジェクトが別のスレッドによって同時に変更されたことを示すとは限りません。単一のスレッドがオブジェクトの契約に違反する一連のメソッド呼び出しを発行する場合、オブジェクトはこの例外をスローする可能性があります。たとえば、スレッドがフェイル・ファースト・イテレータを使用してコレクションを反復している間に、スレッドがコレクションを直接変更した場合、イテレータはこの例外をスローします。

(強調が加えられる)。

私はtree.removeSubscriber(subtupel);subscribersを修正していると推測しています。

+2

彼は2つのスレッドを持っていませんが、反復中にデータ構造をインターリーブして修正しています。 –

+1

はい、私は太字のjavadocの部分を参照してください。 – Taylor

関連する問題