>Java >java지도 시간 >Java에서 ConcurrentModificationException은 어떤 시나리오에서 발생합니까?

Java에서 ConcurrentModificationException은 어떤 시나리오에서 발생합니까?

WBOY
WBOY원래의
2023-06-24 22:27:55687검색

Java中的ConcurrentModificationException异常在什么场景下出现?

ConcurrentModificationException(并发修改异常)是Java中常见的异常之一,当在迭代(遍历)集合时,存在另外一个线程修改了集合中的元素,就会抛出该异常。

ConcurrentModificationException 异常在什么场景下出现?

在多线程环境下,当一个线程在迭代一个集合的过程中,另外一个线程在修改了该集合后就会抛出ConcurrentModificationException异常。简单来说,就是当一个线程正在对集合进行迭代操作,而另一个线程此时对集合进行了添加、删除或修改操作,就会触发该异常。这通常发生在使用Iterator迭代器对集合操作时,因为Iterator只允许单线程对集合进行操作。

例如,在以下例子中,我们使用一个线程对集合进行迭代,在同一时间内另一个线程对集合进行了修改,就会引发ConcurrentModificationException异常:

import java.util.ArrayList;
import java.util.List;
  
public class ConcurrencyTest {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add(i);
        }
 
        new Thread(() -> {
            for (int i : list) {
                System.out.println(i);
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
 
        new Thread(() -> {
            list.add(100);
        }).start();
    }
}

如上代码所示,我们启动两个线程。其中一个线程对集合进行迭代操作,另一个线程则对集合进行添加操作。这里我们使用ArrayList作为集合。

如果运行以上代码,将会看到以下异常抛出:

Exception in thread "Thread-1" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
    at java.util.ArrayList$Itr.next(ArrayList.java:851)
    at ConcurrencyTest.lambda$0(ConcurrencyTest.java:16)

如何解决ConcurrentModificationException异常?

解决ConcurrentModificationException异常的最好方法就是避免此类场景的出现。为了保证线程安全,我们必须通过使用同步操作或并发集合来避免多线程冲突。

Java中的并发集合类如:ConcurrentHashMap,ConcurrentLinkedQueue,CopyOnWriteArrayList等,在多线程程序中,这些集合类可以大大减少多线程冲突的发生。

对于普通的集合类,比如ArrayList、LinkedList、HashMap等,我们可以使用synchronized关键字来保证线程安全。比如,使用synchronized同步代码块来保证在迭代时不被其他线程操作:

import java.util.ArrayList;
import java.util.List;
  
public class ConcurrencyTest {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add(i);
        }
 
        new Thread(() -> {
            synchronized (list) {
                for (int i : list) {
                    System.out.println(i);
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
 
        new Thread(() -> {
            synchronized (list) {
                list.add(100);
            }
        }).start();
    }
}

如上代码所示,我们使用synchronized关键字对迭代和添加进行同步,从而避免了多线程冲突的问题。

总结

ConcurrentModificationException异常在Java中非常常见,尤其是在多线程操作集合的时候。为了避免出现这种异常,我们可以使用并发集合和同步关键字来确保线程安全。在实际开发中,我们必须针对不同场景选择合适的解决方案,以保证程序的健壮性。

위 내용은 Java에서 ConcurrentModificationException은 어떤 시나리오에서 발생합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.