Co to jest wyjątek ConcurrentModificationException w Javie?

„Wyjątek ConcurrentModificationException występuje, gdy zasób jest modyfikowany, nie mając uprawnień do modyfikacji”.
Innymi słowy, wyjątek Java ConcurrentModificationException (jak sama nazwa wskazuje) występuje z powodu problemu współbieżności. Zakłada się, że przed kontynuowaniem masz wiedzę na temat wątków i wielowątkowości . Niektóre klasy w Javie, np. klasy Collection, nie pozwalają wątkowi na modyfikowanie elementu, gdy inny wątek iteruje po nim. Jeśli zostanie wykonana operacja modyfikacji (dodawanie, usuwanie itp.), program zgłasza wyjątek ConcurrentModificationException . To nie jedyny przypadek wystąpienia tego wyjątku. Jednak głębsze kopanie wykracza poza zakres tego artykułu.

Przykład

Przyjrzyjmy się przykładowi wystąpienia tego wyjątku.
import java.util.List;
import java.util.Iterator;
import java.util.ArrayList;

//Test driver for ConcurrentModificationException
public class ConcurrentModificationExceptionTestDriver1 {

	public static void main(String[] args) {
		List<String> businessDays = new ArrayList<>();

		businessDays.add("Monday");
		businessDays.add("Tuesday");
		businessDays.add("Wednesday");
		businessDays.add("Thursday");
		businessDays.add("Friday");
		businessDays.add("Saturday");
		businessDays.add("Sunday");

		Iterator<String> iterator = businessDays.iterator();
		while (iterator.hasNext()) {
			String day = iterator.next();
			if (day.equals("Sunday")) {
				// removing a list item while iterating
				// leading to java.util.ConcurrentModificationException
				businessDays.remove(day);
			}
		}
	}
}

Wyjście

Wyjątek w wątku „main” java.util.ConcurrentModificationException w java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1042) w java.base/java.util.ArrayList$Itr.next(ArrayList.java :996) o milestone.thirty.seven.ConcurrentModificationExceptionTestDriver1.main(ConcurrentModificationExceptionTestDriver1.java:22)

Jak uniknąć wyjątku ConcurrentModificationException w Javie?

Istnieją różne obejścia dla ConcurrentModificationException . Oto lista kilku. Możesz wybrać dowolną osobę według swoich potrzeb.
  1. Unikaj modyfikacji podczas iteracji.
  2. Używaj tradycyjnych pętli do jednoczesnej iteracji i modyfikacji.
  3. Utwórz kopię wartości do modyfikacji podczas korzystania z iteratorów. Zaktualizuj wartości po zakończeniu iteracji.

Przykład

Oto przykład, jak można uniknąć wyjątku ConcurrentModificationException .
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

//Test driver for ConcurrentModificationException
public class ConcurrentModificationExceptionTestDriver2 {

	public static void main(String[] args) {

		List<String> businessDays = new ArrayList<>();

		businessDays.add("Monday");
		businessDays.add("Tuesday");
		businessDays.add("Wednesday");
		businessDays.add("Thursday");
		businessDays.add("Friday");
		businessDays.add("Saturday");
		businessDays.add("Sunday");

		System.out.println("Initial Business Days: " + businessDays);

		// Method II - Using traditional for loop
		for (int i = 0; i < businessDays.size(); i++) {
			if (businessDays.get(i).equals("Sunday")) {
				businessDays.remove(i);
			}
		}

		Iterator<String> iterator = businessDays.iterator();
		List<String> businessDaysToBeRemoved = new ArrayList<>();

		// Method III - Creating a copy of elements
		while (iterator.hasNext()) {
			String day = iterator.next();
			if (day.equals("Saturday")) {
				// Add values to be removed in the list
				businessDaysToBeRemoved.add(day);
			}
		}
		businessDays.removeAll(businessDaysToBeRemoved);
		System.out.println("Final Business Days: " + businessDays);
	}
}

Wyjście

Początkowe dni robocze: [poniedziałek, wtorek, środa, czwartek, piątek, sobota, niedziela] Końcowe dni robocze: [poniedziałek, wtorek, środa, czwartek, piątek]

Wniosek

To była szybka dawka radzenia sobie z wyjątkiem ConcurrentModificationException w Javie. Wskakuj, gdy poczujesz, że utknąłeś. Jak zawsze kluczem do dalszych postępów jest praktyka i cierpliwość. Do tego czasu ucz się i rozwijaj.