当前位置: 移动技术网 > IT编程>开发语言>Java > java 中modCount 详解及源码分析

java 中modCount 详解及源码分析

2019年07月22日  | 移动技术网IT编程  | 我要评论
modcount到底是干什么的呢 在arraylist,linkedlist,hashmap等等的内部实现增,删,改中我们总能看到modcount的身影,modcount

modcount到底是干什么的呢

在arraylist,linkedlist,hashmap等等的内部实现增,删,改中我们总能看到modcount的身影,modcount字面意思就是修改次数,但为什么要记录modcount的修改次数呢?

大家发现一个公共特点没有,所有使用modcount属性的全是线程不安全的,这是为什么呢?说明这个玩意肯定和线程安全有关系喽,那有什么关系呢

阅读源码,发现这玩意只有在本数据结构对应迭代器中才使用,以hashmap为例:

private abstract class hashiterator<e> implements iterator<e> {
    entry<k,v> next;    // next entry to return
    int expectedmodcount;  // for fast-fail
    int index;       // current slot
    entry<k,v> current;   // current entry

    hashiterator() {
      expectedmodcount = modcount;
      if (size > 0) { // advance to first entry
        entry[] t = table;
        while (index < t.length && (next = t[index++]) == null)
          ;
      }
    }

    public final boolean hasnext() {
      return next != null;
    }

    final entry<k,v> nextentry() {
      if (modcount != expectedmodcount)
        throw new concurrentmodificationexception();
      entry<k,v> e = next;
      if (e == null)
        throw new nosuchelementexception();

      if ((next = e.next) == null) {
        entry[] t = table;
        while (index < t.length && (next = t[index++]) == null)
          ;
      }
      current = e;
      return e;
    }

    public void remove() {
      if (current == null)
        throw new illegalstateexception();
      if (modcount != expectedmodcount)
        throw new concurrentmodificationexception();
      object k = current.key;
      current = null;
      hashmap.this.removeentryforkey(k);
      expectedmodcount = modcount;
    }
  }

由以上代码可以看出,在一个迭代器初始的时候会赋予它调用这个迭代器的对象的mcount,如何在迭代器遍历的过程中,一旦发现这个对象的mcount和迭代器中存储的mcount不一样那就抛异常

好的,下面是这个的完整解释

fail-fast 机制

我们知道 java.util.hashmap 不是线程安全的,因此如果在使用迭代器的过程中有其他线程修改了map,那么将抛出concurrentmodificationexception,这就是所谓fail-fast策略。这一策略在源码中的实现是通过 modcount 域,modcount 顾名思义就是修改次数,对hashmap 内容的修改都将增加这个值,那么在迭代器初始化过程中会将这个值赋给迭代器的 expectedmodcount。在迭代过程中,判断 modcount 跟 expectedmodcount 是否相等,如果不相等就表示已经有其他线程修改了 map:注意到 modcount 声明为 volatile,保证线程之间修改的可见性。

所以在这里和大家建议,当大家遍历那些非线程安全的数据结构时,尽量使用迭代器

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网