Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

วิธีหลีกเลี่ยง ConcurrentModificationException ขณะวนลูปคอลเลกชันใน Java

เมื่อทำงานกับอ็อบเจกต์คอลเลกชัน ขณะเธรดหนึ่งกำลังวนลูป (iterating) ผ่านคอลเลกชันหนึ่ง หากคุณพยายามเพิ่มหรือลบองค์ประกอบจากมัน จะเกิด ConcurrentModificationException

ไม่ chỉนั้น หากคุณกำลังวนลูปคอลเลกชัน เพิ่มหรือลบองค์ประกอบ แล้วพยายามวนลูปเนื้อหาอีกครั้ง ถือว่าคุณพยายามเข้าถึงคอลเลกชันด้วยหลายเธรด และ ConcurrentModificationException จะเกิดขึ้น

ตัวอย่าง

import java.util.ArrayList;
import java.util.Iterator;

public class OccurenceOfElements {
    public static void main(String args[]) {
        ArrayList<String> list = new ArrayList<String>();
        // สร้างอ็อบเจกต์ ArrayList
        list.add("JavaFX");
        list.add("Java");
        list.add("WebGL");
        list.add("OpenCV");
        
        System.out.println("Contents of the array list (first to last): ");
        Iterator<String> it = list.iterator();
        
        while(it.hasNext()) {
            System.out.print(it.next() + ", ");
        }
        
        // list.remove(3);
        list.add(3, "Hadoop");
        
        while(it.hasNext()) {
            System.out.print(it.next() + ", ");
        }
    }
}

ผลลัพธ์

Contents of the array list (first to last): JavaFX, Java, WebGL, OpenCV,
Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
    at java.util.ArrayList$Itr.next(Unknown Source)
    at sample.OccurenceOfElements.main(OccurenceOfElements.java:23)

เพื่อแก้ไข ขณะเข้าถึงคอลเลกชันจากหลายเธรด ให้ใช้ synchronized block หรือ method และ หากคุณแก้ไขขณะดึงข้อมูล ให้取得 Iterator object ใหม่หลังจากแก้ไขข้อมูล

ตัวอย่างที่แก้ไขแล้ว

import java.util.ArrayList;
import java.util.Iterator;

public class OccurenceOfElements {
    public static void main(String args[]) {
        ArrayList<String> list = new ArrayList<String>();
        list.add("JavaFX");
        list.add("Java");
        list.add("WebGL");
        list.add("OpenCV");
        
        System.out.println("Contents of the array list (first to last): ");
        Iterator<String> it = list.iterator();
        
        while(it.hasNext()) {
            System.out.print(it.next() + ". ");
        }
        
        list.remove(3);
        System.out.println("");
        System.out.println("Contents of the array list after removal: ");
        
        it = list.iterator(); // ได้ Iterator ใหม่หลังลบ
        
        while(it.hasNext()) {
            System.out.print(it.next() + ". ");
        }
    }
}

ผลลัพธ์

Contents of the array list (first to last): JavaFX. Java. WebGL. OpenCV.
Contents of the array list after removal: JavaFX. Java. WebGL.