`
luozhong915127
  • 浏览: 190088 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
文章分类
社区版块
存档分类
最新评论
阅读更多
java.util.ConcurrentModificationException 
工作中碰到个ConcurrentModificationException。代码如下:
List list = ...;
for(Iterator iter = list.iterator(); iter.hasNext();) {
    Object obj = iter.next();
    ...
    if(***) {
        list.remove(obj);
    }
}
在执行了remove方法之后,再去执行循环,iter.next()的时候,报java.util.ConcurrentModificationException(当然,如果remove的是最后一条,就不会再去执行next()操作了)

下面来看一下源码
public interface Iterator<E> {
    boolean hasNext();
    E next();
    void remove();
}

public interface Collection<E> extends Iterable<E> {
    ...
    Iterator<E> iterator();
    boolean add(E o);
    boolean remove(Object o);
    ...
}
这里有两个remove方法

接下来来看看AbstractList
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {  
//AbstractCollection和List都继承了Collection
    protected transient int modCount = 0;
    private class Itr implements Iterator<E> {  //内部类Itr
        int cursor = 0;
        int lastRet = -1;
        int expectedModCount = modCount;

        public boolean hasNext() {
            return cursor != size();
        }

        public E next() {
            checkForComodification();  //特别注意这个方法
            try {
                E next = get(cursor);
                lastRet = cursor++;
                return next;
            } catch(IndexOutOfBoundsException e) {
                checkForComodification();
                throw new NoSuchElementException();
            }
        }

        public void remove() {
            if (lastRet == -1)
                throw new IllegalStateException();
            checkForComodification();

            try {
                AbstractList.this.remove(lastRet);  //执行remove对象的操作
                if (lastRet < cursor)
                    cursor--;
                lastRet = -1;
                expectedModCount = modCount;  //重新设置了expectedModCount的值,避免了ConcurrentModificationException的产生
            } catch(IndexOutOfBoundsException e) {
                throw new ConcurrentModificationException();
            }
        }

        final void checkForComodification() {
            if (modCount != expectedModCount)  //当expectedModCount和modCount不相等时,就抛出ConcurrentModificationException
                throw new ConcurrentModificationException();
        }
    }    
}

remove(Object o)在ArrayList中实现如下:
public boolean remove(Object o) {
    if (o == null) {
            for (int index = 0; index < size; index++)
        if (elementData[index] == null) {
            fastRemove(index);
            return true;
        }
    } else {
        for (int index = 0; index < size; index++)
            if (o.equals(elementData[index])) {
                fastRemove(index);
                return true;
            }
    }
    return false;
}
private void fastRemove(int index) {
    modCount++;  //只增加了modCount
    ....
}

所以,产生ConcurrentModificationException的原因就是:
执行remove(Object o)方法之后,modCount和expectedModCount不相等了。然后当代码执行到next()方法时,判断了checkForComodification(),发现两个数值不等,就抛出了该Exception。
要避免这个Exception,就应该使用remove()方法。
这里我们就不看add(Object o)方法了,也是同样的原因,但没有对应的add()方法。一般嘛,就另建一个List了

 

1
0
分享到:
评论

相关推荐

    android 异常处理机制

    以下将详细介绍Android异常处理机制及其优化策略。 首先,Android系统在遇到未被捕获的异常时,会触发系统默认的错误报告,弹出“应用无响应”(ANR)对话框,这不仅对用户不友好,也无助于开发者定位问题。为了...

    android 异常捕捉和日志文件保存

    一、Android异常处理 1. **异常分类**:在Android中,异常主要分为两种类型——Checked Exception(已检查异常)和Unchecked Exception(未检查异常)。已检查异常在编译时必须被捕获或声明,如IOException;未检查...

    Android异常日志保存

    "Android异常日志保存"这个Demo提供了一个实用的方法,将应用程序运行时的错误日志保存到设备的外部存储(SD卡)上,以便于开发者进行测试和调试。下面我们将详细探讨这一技术。 1. **Android异常处理基础** 在...

    android 异常崩溃demo

    一、Android异常处理基础 在Android系统中,异常分为检查异常(Checked Exception)和运行时异常(Runtime Exception)。检查异常是可以在编译时期就能发现的,如IOException,需要显式捕获或声明抛出。运行时异常...

    Android异常捕获(发邮件+写文件)

    总结来说,Android异常捕获是提升应用稳定性和用户体验的关键步骤。通过自定义`UncaughtExceptionHandler`,我们可以收集并记录异常信息,甚至在发生异常时主动向开发者报告,以便及时修复问题。在实际开发中,还应...

    Android异常日志捕获

    总结来说,Android异常日志捕获是调试和优化应用的关键步骤。通过使用Log类、自定义异常处理器和高级日志管理策略,开发者可以更好地理解程序运行状态,及时发现并解决问题,提升应用的质量和用户体验。同时,注意...

    android异常收集处理

    在Android中有的未知的Bug可能在测试中没有及时发现,导致用户在使用时出现程序奔溃,出现用户...android提供了Thread.UncaughtExceptionHandler接口,可以通过实现这个接口,在全局中捕获异常并处理,上传到服务器。

    android异常捕获,存在sd卡中

    标题"android异常捕获,存在sd卡中"表明这是一个关于在Android系统中如何捕获并记录应用异常到SD卡上的技术实践。描述中的"app异常信息自动保存在sd卡中"进一步强调了这个机制主要是为了将异常日志存储在外部存储...

    CrashHandler android异常处理

    1. **Android异常处理基础** Android系统默认提供了异常处理机制,但通常只提供简单的堆栈跟踪信息,并不足以进行深入的问题排查。为了提供更全面的错误报告和更好的用户体验,开发者需要自定义异常处理器。 2. **...

    android 异常捕获源码.zip

    总之,"android 异常捕获源码.zip"中的ACRA项目提供了全面的Android异常处理解决方案,对于提高应用的质量和用户体验有着重要的价值。开发者不仅可以直接使用ACRA,也可以借鉴其设计思想,为自己的应用构建更加完善...

    Android异常

    这篇博客主要探讨了Android异常的相关知识,结合源码分析和实用工具的使用,为开发者提供了更深入的理解。 首先,Android异常主要分为两类:系统抛出的异常(System Exception)和应用程序错误(Application Error...

    android 异常10s后重启

    总的来说,解决“Android异常10秒后重启”的问题需要系统地排查,包括查看错误日志、分析崩溃报告、检查硬件状态、更新系统和应用,甚至可能需要专业人员的协助。记住,每次尝试解决方案后,都需要观察设备是否仍然...

    Android异常捕获demo(可以捕获ANR+UncaughtExceptionHandler)

    `Android异常捕获demo`主要展示了如何有效地捕获和处理两种重要的错误类型:应用程序无响应(ANR)和未捕获异常(UncaughtExceptionHandler)。下面我们将深入探讨这两个概念以及如何在实际应用中实现它们。 1. **...

    无法运行android异常捕获存在sd卡中.rar

    "无法运行android异常捕获存在sd卡中.rar"这个文件可能包含了开发者在调试过程中记录的一些错误日志或者异常堆栈信息,这些信息对于诊断和修复问题至关重要。 首先,我们要了解Android中的异常处理机制。在Java编程...

    基于FWKN-SVM的Android异常入侵检测的研究.pdf

    【Android异常入侵检测】 本文研究的是在Android平台上利用一种名为FWKN-SVM(特征加权K最近邻支持向量机)的方法进行异常入侵检测。在移动设备的安全领域,尤其是Android系统,异常入侵检测是保障用户数据安全的...

    Android异常处理最佳实践

    本文将深入探讨"Android异常处理最佳实践",并基于提供的代码示例进行解析。 首先,一个优秀的异常处理机制应具备以下特点: 1. 错误信息上传:为了便于开发者追踪和修复问题,异常处理机制应能捕获错误信息,并将...

    Android异常捕获

    本篇将详细介绍Android异常捕获的原理、实现方法以及如何将错误日志保存到T卡。 首先,Android系统提供了Java语言的异常处理机制,包括try-catch-finally语句块。当try块中的代码出现异常时,会立即跳转到对应的...

    android异常类型和处理

    在Android开发中,异常处理是确保程序稳定性和健壮性的重要环节。Java语言提供了一套完善的异常处理机制,使得开发者能够有效地捕获和处理程序运行过程中可能出现的各种问题。本文将详细探讨Android中常见的异常类型...

    UncaughtException不让Android应用异常退出

    "UncaughtException不让Android应用异常退出"这个主题,就是关于如何处理程序中的未捕获异常,以防止应用突然崩溃,从而提升用户体验。在这个问题上,我们可以从以下几个方面来探讨: 1. **...

    Android-Android异常捕获以及上传到服务器

    在Android应用开发中,异常处理是一项至关重要的任务,它确保了程序在遇到错误时能够以优雅的方式退出,而不是崩溃,从而提高用户体验。本教程将详细讲解如何在Android中实现异常捕获并将其上传到服务器。 首先,...

Global site tag (gtag.js) - Google Analytics