List集合反復中に追加削除に異常が発生し、解決方法
1970 ワード
public void testIterator (){
// ArrayList ,
// java.util.ConcurrentModificationException
List list = new ArrayList();
for(int i = 0 ; i < 10 ; i ++){
list.add(new User(i+""));
}
for(User temp:list){
if(Integer.parseInt(temp.name) % 2 == 0){
list.remove(temp); // ,
}
System.out.print(temp.name + ",");
}
System.out.println("=====");
Iterator it = list.iterator();
while(it.hasNext()){ //
//System.out.println(it.hasNext());
User temp = it.next();
if(Integer.parseInt(temp.name) % 2 == 0){
it.remove();
}
}
for(User temp:list){
System.out.print(temp.name + ",");
}
}
class User{
String name = "";
public User(String name){
this.name = name;
}
}
問題の分析:APIからListなどのCollectionの実現は同期化していないことを見ることができて、もしマルチスレッドアプリケーションの中で同時アクセスが現れるならば、その上修正操作が現れる時すべて外部操作の同期化を要求します;Iteratorを呼び出す操作で得られたIteratorオブジェクトは、マルチスレッドがSetを変更する際にも自動的に失効しjavaを放出する.util.ConcurrentModificationException。この実装メカニズムはfail−fastであり,外部の修正には何の保証も提供できない.
Iteratorは独立したスレッドで動作し、mutexロックを有しています.つまり、Iteratorは動作中に反復されたオブジェクトが変更されることは許されません.Iteratorが作成されると、元のオブジェクトを指すメモリインデックステーブル(単一チェーンテーブル)が作成され、元のオブジェクトの数が変更されると、このインデックステーブルの内容は同期的に変更されないため、インデックスポインタが下に移動すると反復するオブジェクトが見つからず、エラーが発生します.List,Setなどは動的で可変オブジェクト数のデータ構造であるが,Iteratorは一方向に可変ではなく順次しか読み取れず,逆順操作ができないデータ構造であり,Iteratorが指す元のデータが変化すると,Iterator自身は方向を見失う.
解決策:インタフェースであるIreratorのremoveメソッドを呼び出します.
Iterator it = list.iterator();
while(it.hasNext()){ //
//System.out.println(it.hasNext());
User temp = it.next();
if(Integer.parseInt(temp.name) % 2 == 0){
it.remove();
}
}