📜  如何避免Java的ConcurrentModificationException ?

📅  最后修改于: 2022-05-13 01:55:36.424000             🧑  作者: Mango

如何避免Java的ConcurrentModificationException ?

ConcurrentModificationException 是Java的一个预定义异常,它在我们使用Java集合时发生,即每当我们尝试在未经许可的情况下并发修改对象时,就会发生 ConcurrentModificationException,它存在于 Java的.util 包裹。

过程:为了避免在单线程环境中发生此异常,需要一些步骤。它们如下:

  • 我们可以遍历数组而不是遍历集合类。这对于较小的列表非常有效,对于较大的列表呢?我们知道,如果数组大小很大,那么它会影响性能,这是非常基本的。因此,此方法仅对较小尺寸的数组有效。
  • 下一个方法是同步块方法,这里我们实际上将列表锁定在一个同步块中以避免异常。这不是很酷吗?但是猜猜这也不是避免异常的有效方法么?因为没有使用多线程的目的。
  • 更好的方法是我们有 ConcurrentHashMap 和 CopyOnWriteArrayList 这是上述方法中最好的。

方法:

这里提出了两种方法,从最简单的方法开始,以达到目标的最佳方法结束。

  1. 使用循环:我们使用 Iterator remove() 方法而不是我们可以使用 for 循环来避免单线程环境中的 ConcurrentModificationException。如果我们添加任何额外的对象,那么我们可以确保我们的代码处理它们。
  2. 使用 remove() 方法:我们可以使用 remove 方法从集合中删除对象。这里有一个问题是您只能删除相同的对象,而不能从列表中删除任何其他对象

示例 1:



Java
// Java Program to Avoid
// AvoidConcurrentModificationException
 
// Importing Map and List utility classes
//  from java.util package
import java.util.List;
import java.util.Map;
 
// Importing classes from java.util.concurrent package
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
 
// Main class
public class GFG {
 
    // Main driver method
    public static void main(String[] args)
    {
 
        // Creating an object of List class
        // Declaring object of string type
        List marvel
            = new CopyOnWriteArrayList();
 
        // Adding elements to the above object created
        // Custom input entries
        marvel.add("IronMan");
        marvel.add("BlackWidow");
        marvel.add("Hulk");
        marvel.add("DoctorStrange");
        marvel.add("SpiderMan");
 
        // Iterating over object created using size() method
        for (int i = 0; i < marvel.size(); i++) {
 
            // Print and display the object elements
            // using get() method
            System.out.println("Avenger : "
                               + marvel.get(i));
 
            // Condition check over object elements
 
            // If specific element is matched
            if (marvel.get(i).equals("BlackWidow")) {
 
                marvel.remove(i);
                i--;
 
                // Add this specific element
                marvel.add("CaptianAmerica");
            }
        }
 
        // Now getting the final total size by checking
        // how many elements are there inside object
        System.out.println("Total Avengers : "
                           + marvel.size());
    }
}


Java
// Java Program to Illustrate ConcurrentModificationException
// WithArrayListSubList
 
// Importing List and Arraylist classes utility classes
// from java.util package
import java.util.ArrayList;
import java.util.List;
 
// Main class
public class GFG {
 
    // Main driver method
    public static void main(String[] args) {
 
        // Creating a List class object
        // Declaring object of string type
        List  names = new ArrayList <>();
 
        // Adding elements to the object of List class
 
        // Custom input entries
        names.add("Java");
        names.add("C++");
        names.add("Phython");
        names.add("JavaScript");
 
        List < String > first2Names = names.subList(0, 2);
 
        System.out.println(names + " , " + first2Names);
 
        names.set(1, "Ruby");
 
        // check the output below. 🙂
        System.out.println(names + " , " + first2Names);
 
        // Now we add another string to
        // get ConcurrentModificationException
        names.add("SQL");
 
        // This line throws an exception
        System.out.println(names + " , " + first2Names);
 
    }
}



输出
Avenger : IronMan
Avenger : BlackWidow
Avenger : Hulk
Avenger : DoctorStrange
Avenger : SpiderMan
Avenger : CaptianAmerica
Total Avengers :5

示例 2:

Java

// Java Program to Illustrate ConcurrentModificationException
// WithArrayListSubList
 
// Importing List and Arraylist classes utility classes
// from java.util package
import java.util.ArrayList;
import java.util.List;
 
// Main class
public class GFG {
 
    // Main driver method
    public static void main(String[] args) {
 
        // Creating a List class object
        // Declaring object of string type
        List  names = new ArrayList <>();
 
        // Adding elements to the object of List class
 
        // Custom input entries
        names.add("Java");
        names.add("C++");
        names.add("Phython");
        names.add("JavaScript");
 
        List < String > first2Names = names.subList(0, 2);
 
        System.out.println(names + " , " + first2Names);
 
        names.set(1, "Ruby");
 
        // check the output below. 🙂
        System.out.println(names + " , " + first2Names);
 
        // Now we add another string to
        // get ConcurrentModificationException
        names.add("SQL");
 
        // This line throws an exception
        System.out.println(names + " , " + first2Names);
 
    }
}




输出:

此后,我们讨论了如何在单线程和多线程环境中成功避免异常,如上述输出所示。