CodeGym /Java Blog /Toto sisi /Java 中的並發修改異常
John Squirrels
等級 41
San Francisco

Java 中的並發修改異常

在 Toto sisi 群組發布

Java中的ConcurrentModificationException是什麼?

“當在沒有修改權限的情況下修改資源時,會發生 ConcurrentModificationException。”
換句話說,Java ConcurrentModificationException(顧名思義)是由於並發問題而發生的。在繼續操作之前,假定您已具備執行緒多執行緒 的先驗知識。Java 中的某些類別(如 Collection 類別)不允許一個執行緒在另一個執行緒迭代元素時修改該元素。如果執行修改操作(新增、刪除等),程式將會拋出ConcurrentModificationException。這並不是發生此異常的唯一情況。然而,更深入的挖掘超出了本文的範圍。

例子

讓我們來看一個例子來說明這個異常是如何發生的。
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);
			}
		}
	}
}

輸出

線程「main」中的異常java.util.ConcurrentModificationException 在java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1042) 在java.base/java.util.ArrayList$Itr.next(ArrayList. java :996)在milestone.thirty.seven.ConcurrentModificationExceptionTestDriver1.main(ConcurrentModificationExceptionTestDriver1.java:22)

Java中如何避免ConcurrentModificationException?

ConcurrentModificationException有不同的解決方法。這裡列出了一些。您可以根據您的需求選擇任何人。
  1. 避免迭代時修改。
  2. 使用傳統循環進行同時迭代和修改。
  3. 建立要在使用迭代器時修改的值的副本。迭代結束後更新值。

例子

以下是如何避免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);
	}
}

輸出

初始工作日:[週一、週二、週三、週四、週五、週六、週日] 最終工作日:[週一、週二、週三、週四、週五]

結論

這是處理Java 中的ConcurrentModificationException的快速方法。每當您感到卡住時,請隨時跳上來。一如既往,前進的關鍵是練習和耐心。在那之前,繼續學習並不斷成長。
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION