ConcurrentModificationException w Java jest wyjątkiem, który może pojawić się podczas modyfikacji kolekcji, gdy jednocześnie trwa przez nią iteracja. Jest to typowy błąd, który występuje w wielowątkowych aplikacjach, ale może się zdarzyć także w pojedynczym wątku, gdy kolekcja jest modyfikowana podczas iteracji. Zrozumienie tego błędu oraz sposobów jego unikania jest kluczowe dla bezpiecznego i efektywnego zarządzania kolekcjami w Java.
Przykład kodu
Załóżmy, że mamy listę, po której iterujemy, jednocześnie próbując usunąć z niej elementy. Oto przykład, jak to zazwyczaj się robi i dlaczego prowadzi to do błędu:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ConcurrentModificationExample {
public static void main(String[] args) {
List<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Cherry");
// Iterator do przeglądania listy
Iterator<String> iterator = fruits.iterator();
while (iterator.hasNext()) {
String fruit = iterator.next();
// Sprawdzamy, czy owoc to "Banana"
if (fruit.equals("Banana")) {
// Próba usunięcia elementu podczas iteracji
fruits.remove(fruit); // Tutaj pojawi się ConcurrentModificationException
}
}
}
}
W powyższym kodzie, podczas gdy iterujemy po liście fruits
za pomocą iteratora, próbujemy usunąć element “Banana” bezpośrednio z listy. Modyfikacja listy w trakcie iteracji prowadzi do wygenerowania ConcurrentModificationException, ponieważ struktura listy została zmieniona, a iterator o tym nie wie.
Lepsze podejście do usuwania elementów
Aby uniknąć tego błędu, powinniśmy korzystać z metody remove
dostarczanej przez iterator, która jest bezpieczna do używania podczas iteracji:
while (iterator.hasNext()) {
String fruit = iterator.next();
if (fruit.equals("Banana")) {
// Bezpieczne usunięcie elementu za pomocą iteratora
iterator.remove(); // Teraz nie pojawi się wyjątek
}
}
Podsumowanie
ConcurrentModificationException jest wynikiem modyfikacji kolekcji podczas iteracji bez odpowiedniego uwzględnienia mechanizmów synchronizacji. Najprostszym sposobem uniknięcia tego błędu jest użycie metody remove
iteratora, która jest synchronizowana z bieżącym stanem kolekcji i zapewnia, że struktura kolekcji nie zostanie naruszona podczas iteracji. Pamiętanie o tej zasadzie i stosowanie jej w praktyce jest kluczowe dla pisania bezpiecznego i stabilnego kodu w języku Java.
Jeżeli chcesz przyśpieszyć swoją naukę tworzenia stron chciałbym polecić mój kurs video Java w którym nauczysz się tego języka od podstaw do zaawansowanych jego aspektów.