Home  >  Article  >  Java  >  In what scenarios does ConcurrentModificationException occur in Java?

In what scenarios does ConcurrentModificationException occur in Java?

WBOY
WBOYOriginal
2023-06-24 22:27:55641browse

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

The above is the detailed content of In what scenarios does ConcurrentModificationException occur in Java?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn