ホームページ  >  記事  >  Java  >  Java で ConcurrentModificationException が発生する一般的な原因は何ですか?

Java で ConcurrentModificationException が発生する一般的な原因は何ですか?

PHPz
PHPzオリジナル
2023-06-25 11:07:401419ブラウズ

Java における ConcurrentModificationException の一般的な原因は何ですか?

Java コレクション フレームワークの反復子を使用してコレクションを走査すると、ConcurrentModificationException 例外がスローされることがあります。これは、一般的な Java 例外の 1 つです。では、この例外の理由は何でしょうか?

まず、Java コレクション フレームワークによって提供されるイテレータがステートフルであることを理解する必要があります。つまり、トラバーサル中に状態が変化すると、例外がスローされる可能性があります。

一般的な ConcurrentModificationException 例外の原因は次のとおりです:

1. コレクションを反復するときに、その構造が変更されると (要素の追加または削除など)、ConcurrentModificationException 例外がスローされます。

たとえば、要素の追加や削除など、foreach イテレータを使用して ArrayList の内容を直接変更すると、ConcurrentModificationException がスローされます。

List<String> list = new ArrayList<>();
list.add("Java");
list.add("C++");
list.add("Python");

for(String s : list){
    if(s.equals("Java")){
        list.remove(s); //这句会抛出ConcurrentModificationException异常
    }
}

2. コレクションを反復するときに、その構造が変更されると、別の反復子が ConcurrentModificationException 例外をスローする可能性があります。

たとえば、Iterator を使用して ArrayList を走査し、別のスレッドを使用して要素を追加または削除すると、ConcurrentModificationException がスローされます。

List<String> list = new ArrayList<>();
list.add("Java");
list.add("C++");
list.add("Python");

Iterator<String> iterator = list.iterator();

while(iterator.hasNext()){
    String s = iterator.next();
    if(s.equals("Java")){
        list.remove(s); //在另一个线程中添加或删除元素,就会抛出ConcurrentModificationException异常
    }
}

3. コレクションを反復するときに、その構造が変更されると、異なる反復子は異なる動作を示す可能性があります。

たとえば、ArrayList の反復子の走査中に要素を追加または削除すると、走査操作中の ArrayList のパフォーマンスと期待が低下します。さらに、Iterator は無限ループに入ったり、ConcurrentModificationException をスローしたりする可能性があります。

List<String> list = new ArrayList<>();
list.add("Java");
list.add("C++");
list.add("Python");

Iterator<String> iterator1 = list.iterator();
Iterator<String> iterator2 = list.iterator();

while(iterator1.hasNext()){
    String s = iterator1.next();
    if(s.equals("Java")){
        list.remove(s); //会抛出ConcurrentModificationException异常
    }
    while(iterator2.hasNext()){
        // 进入无限循环
    }
}

要約:

Java コレクション フレームワークによって提供される反復子はステートフルです。反復子がコレクションを走査すると、走査された要素の位置などの現在の状態が記録されます。情報。 。トラバーサル プロセス中に構造が変更されると、ConcurrentModificationException がスローされます。

したがって、コレクションを走査するときは、ループ本体内でコレクションの内容を直接変更しないように注意してください。変更しないと、例外がスローされます。変更する必要がある場合は、イテレータのremove()メソッドを使用して削除できます。複数のスレッドがコレクションを同時に変更する場合は、ConcurrentModificationException をスローしないように注意してください。

以上がJava で ConcurrentModificationException が発生する一般的な原因は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。