ModCount属性意义

2019-05-22  本文已影响0人  small瓜瓜
    //在ArrayList中
    protected transient int modCount = 0;

    //在HashMap中
    transient int modCount;
    
    //在LinkedList中
    protected transient int modCount = 0;

上面的代码是在ArrayList、HashMap、LinkedList中找到的,属性名一样,定义方式类似。
transient这个关键字主要就是让对象序列化时忽略modCount

我们来看看属性的说明

在结构上修改这个HashMap的次数,结构修改是指改变映射的数量HashMap或以其他方式修改其内部结构(例如重复)。此字段用于在集合视图上生成迭代器HashMap失败得很快。(见ConcurrentModificationException)。

有道翻译可能不太好理解,那我们直接上代码吧

    代码copy于ArrayList中
    @Override
    public void forEach(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        final int expectedModCount = modCount;
        final Object[] es = elementData;
        final int size = this.size;
        for (int i = 0; modCount == expectedModCount && i < size; i++)
            action.accept(elementAt(es, i));
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
    }

在ArrayList中我们可以看到

final int expectedModCount = modCount;
//.....//
if (modCount != expectedModCount)
            throw new ConcurrentModificationException();

然后后面进行if判断modCount != expectedModCountexpectedModCount的值是从modCount来在这段代码中并未对两个变量进行修改,他们怎么会不相等呢?这里是不是属于代码冗余呢?
如果您也有这样的疑问的话。那么这篇博客你就看的值了。
如果是单线程中这的确是冗余的,但是一旦到了多线程中,其他线程对这个ArrayList的实例进行了一个add remove等操作,改变了ArrayList数据结构。那么modCount就改变了,同样modCount != expectedModCount也就成立了,本次遍历有误,抛出异常
查看他们的源码可以看到很多方法用ModCount判断结构

所以我们可以看出ArrayList、LinkedList、HashMap等是线程不安全的。

上一篇下一篇

猜你喜欢

热点阅读