1、使用for循环进行遍历集合,在for循环中做增删操作。
2、用Iterator遍历,使用iterator.remove().
当不允许这样的修改时,检测到对象的并发修改的方法可能抛出此异常。
例如,一个线程通常不允许修改Collection,而另一个线程正在迭代它。通常,在这些情况下,迭代的结果是不确定的。如果检测到此行为,某些Iterator实现(包括JRE提供的所有通用集合实现的实现)可能会选择抛出此异常。执行此操作的迭代器称为故障快速迭代器,因为它们快速且干净地失败,而不是在未来的未确定时间冒着任意的,非确定性行为的风险。
请注意,此异常并不总是表示某个对象已被另一个线程同时修改。如果单个线程发出违反对象合同的一系列方法调用,则该对象可能会抛出此异常。例如,如果线程在使用失败快速迭代器迭代集合时直接修改集合,则迭代器将抛出此异常。
请注意,无法保证快速失败的行为,因为一般来说,在存在不同步的并发修改时,不可能做出任何硬性保证。快速失败的操作
ConcurrentModificationException是尽最大努力的。因此,编写依赖于此异常的程序的正确性 是错误的:ConcurrentModificationException应该仅用于检测错误。
//出现java.util.ConcurrentModificationException
List<Device> list = menuAdapter.getDataList().get(index).getDevices();
for (Device device : list) {
if (Constant.DEVICE_STATE_AUDIT.equals(device.getState())) {
list.remove(device);
}
}
deviceAdapter.setDataList(list);
//用Iterator遍历完美解决
List<Device> list = menuAdapter.getDataList().get(index).getDevices();
Iterator<Device> iterator = list.iterator();
while (iterator.hasNext()) {
Device device = iterator.next();
if (Constant.DEVICE_STATE_AUDIT.equals(device.getState())) {
iterator.remove();
}
}
deviceAdapter.setDataList(list);
//使用for循环遍历完美解决
List<Device> list = menuAdapter.getDataList().get(index).getDevices();
for (int i = 0; i < list.size(); i++) {
Device device = list.get(i);
if (Constant.DEVICE_STATE_AUDIT.equals(device.getState())) {
list.remove(i);
}
}
deviceAdapter.setDataList(list);
在Java中,当一个线程尝试遍历并修改集合时,其他线程也在修改该集合,可能会抛出ConcurrentModificationException。使用Iterator的remove()方法或在for-each循环外迭代并删除元素可以避免这个问题。此外,提到使用for循环时,通过索引删除元素也是安全的方法之一。
625

被折叠的 条评论
为什么被折叠?



