Java中的ConcurrentModificationException及示例


Java 中,如果在 多執行緒Java 環境中任何特定方法在資源檢測期間遇到併發情況,則可能會丟擲 ConcurrentModificationException。在此過程中,物件在此處是非允許單元。

這是一個與 **Java 中的 ConcurrentModificationException** 相關的示例:

Exception in thread "main" java.util.ConcurrentModificationException
at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:000)
at java.base/java.util.ArrayList$Itr.next(ArrayList.java:000)
atcom.journaldev.ConcurrentModificationException.ConcurrentModificationExceptio
nExample.main(ConcurrentModificationExceptionExample.java:00)

在此特定過程中,異常會在以下情況下出現:

  • 檢測到異常,並且迭代在方法中未定義。

  • 當程序被快速失敗迭代器中的迴圈阻塞時,使用名為 modCount 的內部標誌。

Java中ConcurrentModificationException的演算法

在這個可能的演算法中,我們將向您展示如何在Java環境中執行java.util.ConcurrentModificationException。透過使用這個可能的演算法,我們將構建一些Java語法,透過它我們將進一步探索一些Java方法。

  • 步驟 1 - 開始程序。

  • 步驟 2 - 宣告並匯入一些Java包以執行程序。

  • 步驟 3 - 宣告一個公共類。

  • 步驟 4 - 宣告一個字串引數。

  • 步驟 5 - 建立一個ArrayList物件。

  • 步驟 6 - 建立一個新的ArrayList。

  • 步驟 7 - 填充ArrayList。

  • 步驟 8 - 宣告一個try函式。

  • 步驟 9 - 為列表宣告一個列印符號。

  • 步驟 10 - 宣告一個迭代器類。

  • 步驟 11 - 繼續獲取下一個值。

  • 步驟 12 - 在迭代之間新增一個值。

  • 步驟 13 - 列印更新後的ArrayList。

  • 步驟 14 - 繼續獲取下一個值。

  • 步驟 15 - 捕獲異常值。

  • 步驟 16 - 列印異常值。

  • 步驟 17 - 獲取值。

  • 步驟 18 - 終止程序。

Java中ConcurrentModificationException的語法

for(int i = 0; i<myList.size(); i++){
	System.out.println(myList.get(i));
	if(myList.get(i).equals("3")){
		myList.remove(i);
		i--;
		myList.add("6");
   }
}
public static void main(String[] args) {
   ArrayList<Integer> list = new ArrayList<>();
   list.add(ELEMENT);
   list.add(ELEMENT);
   list.add(ELEMENT);
   list.add(ELEMENT);
   list.add(ELEMENT);
   //Add more element if the user wants
   Iterator<Integer> it = list.iterator();
   while (it.hasNext()) {
      Integer value = it.next();
	  System.out.println("List Value:" + value);
	  if (value.equals(3))
	  list.remove(value);
   }{
      HashMap<Integer, Integer> map = new HashMap<>();
      map.put(ELEMENT 1, ELEMENT 1);
      map.put(ELEMENT 2, ELEMENT 2);
      map.put(ELEMENT 3, ELEMENT 3);
      Iterator<Integer> it = map.keySet().iterator();
      while(it.hasNext()) {
         Integer key = it.next();
         System.out.println("Map Value:" + map.get(key));
         if (key.equals(SEARCH ELEMENT)){
	        map.put(ELEMENT 1, ELEMENT 4);
         }
      }
   }
 }

在上面的這個可能的語法中,我們試圖向您展示如何在Java環境中宣告和執行一個程序以實現ConcurrentModificationException。透過使用這些語法,我們正在朝著解決給定問題陳述的一些可能方法邁進。

遵循的方法

  • 方法 1 - Java程式透過在迭代過程中新增元素並執行修改來說明ConcurrentModificationException

  • 方法 2 - Java程式透過使用iterator.next()、remove()函式以及部署迴圈來說明java.util.ConcurrentModificationException方法

方法 1:使用迭代過程並執行修改過程

元素新增方法的使用

在這種可能的方法中,我們將對特定集合應用迭代方法。當我們遍歷時,我們直接應用修改過程來進行一些更正。當整個過程無法快速迭代時,在那個特定點會發生異常。

for (Iterator<Integer> iterator = integers.iterator(); iterator.hasNext();) {
	Integer integer = iterator.next();
	if(integer == 2) {
		iterator.remove();
	}
}

示例

//Java program to illustrate the ConcurrentModificationException by using as an element is added during the iteration process
import java.util.Iterator;
import java.util.ArrayList;
public class ARBRDDmodificationError {
   public static void main(String args[]){
      ArrayList<String> arr
      = new ArrayList<String>();
      arr.add("ARB");
      arr.add("Bangladesh");
      arr.add("RDD");
      arr.add("India");
      try {
         System.out.println(
         "ArrayList: ");
         Iterator<String> iter
         = arr.iterator();
         while (iter.hasNext()) {
            System.out.print(iter.next()
            + "-;-");
            System.out.println(
            "\n\nTrying to add"
            + " an element in "
            + "between iteration\n");
            arr.add("Five");
         }
      }
      catch (Exception e) {
         System.out.println(e);
      }
   }
}

輸出

ArrayList:
ARB-;-Trying to add an element in between iteration
java.util.ConcurrentModificationException

迭代器修改方法的使用

在這種可能的方法中,我們將應用修改過程,當異常作為迭代後的修改被引發時。當我們這樣做時,我們可以避免此異常:

  • 迭代結束後再進行修改。

  • 當我們應用同步塊或方法時。

示例

//Java program to show ConcurrentModificationException when exception is raised as a modification is done after the iteration
import java.util.Iterator;
import java.util.ArrayList;
public class ARBRDDmodificationError {
   public static void main(String args[]){
      ArrayList<String> arr
      = new ArrayList<String>();
      arr.add("ARB");
      arr.add("BANGLADESH");
      arr.add("RDD");
      arr.add("INDIA");
      try {
         System.out.println(
         "ArrayList Is Here: ");
         Iterator<String> iter
         = arr.iterator();
         while (iter.hasNext()) {
            System.out.print(iter.next()
            + "_;_");
         }
         System.out.println(
         "\n\nTrying to add"
         + " an element in "
         + "between iteration: "
         + arr.add("Going Soon"));
         System.out.println(
         "\nUpdated ArrayList Is Here: ");
         iter = arr.iterator();
         while (iter.hasNext()) {
            System.out.print(iter.next()
            + "-;-");
         }
      }
      catch (Exception e) {
         System.out.println(e);
      }
   }
}

輸出

ArrayList Is Here:
ARB_;_BANGLADESH_;_RDD_;_INDIA_;_Trying to add an element in between iteration:
true
Updated ArrayList Is Here:
ARB-;-BANGLADESH-;-RDD-;-INDIA-;-Going Soon-;-

方法 2:使用Iterator.next()、Remove()函式以及部署迴圈

Iterator.next()方法的使用

在這種可能的方法中,我們將應用iterator.next()方法。當Java集合類失敗時,這意味著集合在某些執行緒遍歷迭代器時改變了其過程。

@Test(expected = ConcurrentModificationException.class)
public void whilstRemovingDuringIteration_shouldThrowException() throws
InterruptedException {
	List<Integer> integers = newArrayList(1, 2, 3);
	for (Integer integer : integers) {
		integers.remove(1);
	}
}
List<Integer> integers = newArrayList(1, 2, 3);
List<Integer> toRemove = newArrayList();
for (Integer integer : integers) {
	if(integer == 2) {
		toRemove.add(integer);
	}
}
integers.removeAll(toRemove);
assertThat(integers).containsExactly(1, 3);

示例

//Java program to illustrate the java.util.ConcurrentModificationException method by using the iterator.next() function
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class ConcurrentModificationExceptionARBRDDExample {
   public static void main(String args[]) {
      List<String> myList = new ArrayList<String>();
      myList.add("16");
      myList.add("07");
      myList.add("10");
      myList.add("2001");
      myList.add("1997");
      Iterator<String> it = myList.iterator();
      while (it.hasNext()) {
         String value = it.next();
         System.out.println("List Value Is Here. Have A Look @ARBRDD:-->" + value);
         if (value.equals("2001"))
         myList.remove(value);
      }
      Map<String, String> myMap = new HashMap<String, String>();
      myMap.put("16", "16");
      myMap.put("07", "07");
      myMap.put("1997", "1997");
      Iterator<String> it1 = myMap.keySet().iterator();
      while (it1.hasNext()) {
         String key = it1.next();
         System.out.println("Map Value:" + myMap.get(key));
         if (key.equals("07")) {
            myMap.put("16", "2001");
         }
      }
   }
}

輸出

List Value Is Here. Have A Look @ARBRDD:-->16
List Value Is Here. Have A Look @ARBRDD:-->07
List Value Is Here. Have A Look @ARBRDD:-->10
List Value Is Here. Have A Look @ARBRDD:-->2001
Map Value:1997
Map Value:16
Map Value:07

在陣列上使用迴圈

在這種可能的方法中,我們將應用單個執行緒並向其中新增一些額外的物件。當我們嘗試使用特定子列表修改整個結構時,可以實現ConcurrentModificationException。

示例

//Java program to illustrate and deploy a loop to avoid java.util.ConcurrentModificationException in an array list
import java.util.ArrayList;
import java.util.List;
public class ConcurrentModificationExceptionWithArrayListSubList {
   public static void main(String[] args) {
      List<String> names = new ArrayList<>();
      names.add("Kollam");
      names.add("Dhaka");
      names.add("Chennai");
      names.add("Palani");
      List<String> first2Names = names.subList(0, 2);
      System.out.println(names + " , " + first2Names);
      names.set(1, "Kolkata");
      System.out.println(names + " , " + first2Names);
      names.add("Kochi");
      System.out.println(names + " , " + first2Names);
   }
}

輸出

[Kollam, Dhaka, Chennai, Palani] , [Kollam, Dhaka]
[Kollam, Kolkata, Chennai, Palani] , [Kollam, Kolkata]
Exception in thread "main" java.util.ConcurrentModificationException
at
java.base/java.util.ArrayList$SubList.checkForComodification(ArrayList.java:141
5)
at java.base/java.util.ArrayList$SubList.listIterator(ArrayList.java:1284)
at java.base/java.util.AbstractList.listIterator(AbstractList.java:313)
at java.base/java.util.ArrayList$SubList.iterator(ArrayList.java:1280)
at java.base/java.util.AbstractCollection.toString(AbstractCollection.java:451)
at java.base/java.lang.String.valueOf(String.java:4225)
at
ConcurrentModificationExceptionWithArrayListSubList.main(ConcurrentModification
ExceptionWithArrayListSubList.java:16)

Remove()迭代器方法的使用

在這種可能的方法中,我們將應用remove()方法。透過使用它,我們將從列表中刪除相同的物件,而不是任何物件。

示例

//Java program to avoid the ConcurrentModificationException in single-threaded environment by using the iterator to remove() a function
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
public class AvoidConcurrentModificationException{
   public static void main(String[] args){
      List<String> myList = new CopyOnWriteArrayList<String>();
      myList.add("16");
      myList.add("07");
      myList.add("10");
      myList.add("2001");
      myList.add("1997");
      Iterator<String> it = myList.iterator();
      while (it.hasNext()) {
         String value = it.next();
         System.out.println("List Value:" + value);
         if (value.equals("3")) {
            myList.remove("4");
            myList.add("6");
            myList.add("7");
         }
      }
      System.out.println("List Size Is Now :" + myList.size());
      Map<String, String> myMap = new ConcurrentHashMap<String,
      String>();
      myMap.put("16", "07");
      myMap.put("2", "16");
      myMap.put("2022", "13110");
      Iterator<String> it1 = myMap.keySet().iterator();
      while (it1.hasNext()) {
         String key = it1.next();
         System.out.println("Map Value Is Here:" + myMap.get(key));
         if (key.equals("1")) {
            myMap.remove("3");
            myMap.put("4", "4");
            myMap.put("5", "5");
         }
      }
      System.out.println("Map Size Is Here. Have A Look:" +
      myMap.size());
   }
}

輸出

List Value:16
List Value:07
List Value:10
List Value:2001
List Value:1997
List Size Is Now :5
Map Value Is Here:16
Map Value Is Here:07
Map Value Is Here:13110
Map Size Is Here. Have A Look:3

結論

當特定物件嘗試以併發方式修改自身時,可能會遇到ConcurrentModificationException。在今天的文章中,我們學習了併發方法的修改。透過使用上述語法和演算法,我們構建了一些Java程式碼以有效地解決問題陳述。

另請閱讀: Java面試問題及答案

更新於:2024年6月17日

瀏覽量:158

開啟您的職業生涯

透過完成課程獲得認證

開始學習
廣告