【无标题】

Java 中的 ConcurrentModificationException
ConcurrentModificationException 在不允许同时修改对象时发生。当使用Java Collection 类时,通常会出现此异常。

例如- 当某个其他线程正在对其进行迭代时,不允许线程修改 Collection。这是因为迭代的结果变得不确定。Iterator 类的某些实现会引发此异常,包括 JRE 提供的所有 Iterator 的通用实现。这样做的迭代器被称为快速失败,因为它们在遇到这种情况时会立即抛出异常,而不是在未来任何时候面临集合的未确定行为。

注意:仅当某些其他线程尝试修改 Collection 对象时才抛出此异常不是强制性的。如果单个线程调用了一些试图违反对象契约的方法,也会发生这种情况。当一个线程试图修改 Collection 对象时,可能会发生这种情况,同时它正在被一些快速失败的迭代器迭代,迭代器将抛出异常。
例子
Example
import java.awt.List;
import java.util.*;

public class Concurrentmodificationexception {

public static void main(String[] args) {  
    ArrayList<Integer> list = new ArrayList<>();  

    list.add(1);  
    list.add(2);  
    list.add(3);  
    list.add(4);  
    list.add(5);  

    Iterator<Integer> it = list.iterator();  
    while (it.hasNext()) {                   

Integer value = it.next();
System.out.println(“List Value:” + value);
if (value.equals(3))
list.remove(value);
}

}  

}
Output:
输出:

Java 中的 ConcurrentModificationException
该消息表示当调用下一个方法时抛出异常,因为迭代器正在迭代列表并且我们同时对其进行修改。但是如果我们像下面给出的那样对 hashmap 进行修改,那么它不会抛出任何异常,因为 hashmap 的大小不会改变。

For Example-

import java.awt.List;
import java.util.*;

public class concurrentmodificationexception {

public static void main(String[] args) {  
      
    HashMap<Integer, Integer> map = new HashMap<>();  
    map.put(1, 1);  
    map.put(2, 2);  
    map.put(3,3);  
      
    Iterator<Integer> it = map.keySet().iterator();  
    while(it.hasNext()) {  
        Integer key = it.next();  
        System.out.println("Map Value:" + map.get(key));  
        if (key.equals(2)) {  
            map.put(1, 4);  
        }  
    }     
}  

}
Output:

Map Value:1
Map Value:2
Map Value:3
这个例子工作得很好,因为当迭代器在map上迭代时,map的大小并没有改变。if 语句中仅更新map。

ConcurrentModificationException 的构造函数
ConcurrentModificationException 的构造函数有 4 种类型 -

public ConcurrentModificationException() -
这将创建一个没有参数的 ConcurrentModificationException。
public ConcurrentModificationException(String message)
这将创建一个 ConcurrentModificationException,其中包含指定异常的详细消息。
public ConcurrentModificationException(Throwable Cause)
这将创建一个 ConcurrentModificationException,其原因和消息为 (causenull?null:cause.toString())。原因稍后由 Throwable.getCause() 检索。
public ConcurrentModificationException(String message, Throwable cause)
这将创建一个带有详细消息和原因的 ConcurrentModificationException。(cause
null?null:cause.toString())。该消息稍后由 Throwable.getMessage() 检索,原因随后由 Throwable.getCause() 检索。
如何在多线程环境中避免 ConcurrentModificationException?
为了避免在多线程环境中出现 ConcurrentModificationException,我们可以遵循以下方法-

我们可以遍历数组,而不是遍历集合类。这样,我们可以很好地处理小型列表,但是如果数组非常大,这会降低性能。
另一种方法可以通过将列表放在同步块中来锁定列表。这不是一种有效的方法,因为它放弃了使用多线程的唯一目的。
JDK 1.5 或更高版本提供了 ConcurrentHashMap 和 CopyOnWriteArrayList 类。这些类帮助我们避免并发修改异常。
如何在单线程环境中避免 ConcurrentModificationException?
通过使用迭代器的 remove() 函数,您可以从底层集合对象中删除一个对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值