6

私はこの「Freuqent Java concurrency problems」の質問を読んでいて、 java.util.ConcurrentModificationExceptionに関する回答に混乱しました。

私の理解では、これはシングル スレッド プログラムで発生する可能性があります。次のコードが例外をスローする原因は、どのように、またはどのような条件ですか?

List<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c"));
for (String string : list) { list.remove(string); }
4

3 に答える 3

14

このスニペットは常に。をスローしConcurrentModificationExceptionます。

ルールは次のとおりです。イテレータを使用して反復処理している間は、変更(リストの要素の追加または削除)を行うことはできません(これは、for-eachループを使用する場合に発生します)。

ただし、Iterator.removeまたはを使用して、イテレータを介してリストを変更できることに注意してください(変更を認識し、それを考慮に入れることができるため) ListIterator.add

ドキュメントから:

このクラスのイテレータメソッドとlistIteratorメソッドによって返されるイテレータはフェイルファストです。イテレータの作成後にリストが構造的に変更された場合、イテレータ自体のremoveまたはaddメソッド以外の方法で、イテレータはConcurrentModificationExceptionをスローします。

ここでの同時という言葉は、トラバーサルにリストを変更していることを意味します。

于 2011-02-19T16:20:02.567 に答える
2

リストをループしながら変更します。

ここでConcurrentModificationExceptionはスレッドとは何の関係もありません。

警告!次の例は、コレクションを変更するときにコレクションを使用することがどのように危険であるかを示すためのものです。OPの場合(イテレータをループして変更する)で正確に起こったことではありません

次のようなカウンターを備えた昔ながらのループを使用すると、何が問題になっているのかを想像しやすくなると思います。

List<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c"));

for (int i = 0; i < list.size(); i++) { 
   list.remove(i);  //removes element at given index
} 

これで、初回iは0になり、0番目の要素が削除されます。2回目iは1なので、1番目の要素が削除されます。しかし、最初の削除の前に、現在1番目であるものは2番目でした。したがって、以前は1番目でしたが、現在は0番目であるものが削除されることはありません。

于 2011-02-19T16:18:55.903 に答える
2

リストから削除し、同時にイテレータを使用して反復しているためです。

イテレータを使用した同等のコードを参照してください。

import java.lang.*;
import java.util.*;

class Test{
  public static void main(String[] argv){
      List<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c"));
      Iterator<String> itr=list.iterator();
      while(itr.hasNext()){
          String a=itr.next();
           list.remove(a);
      }
   }
}

正しいコードは

import java.lang.*;
import java.util.*;

class Test{
  public static void main(String[] argv){
      List<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c"));
      Iterator<String> itr=list.iterator();
      while(itr.hasNext()){
          itr.remove();
      }
   }
}
于 2011-02-19T16:31:08.330 に答える