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 中国語 Web サイトの他の関連記事を参照してください。