在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,保证线程之间修改的可见性。



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

转载地址:http://blog.csdn.net/u012926924/article/details/50452411

最新文章

  1. Java 中的 Filter 过滤器详解
  2. 离线更新VSAN HCL数据库
  3. Topcoder几例C++字符串应用
  4. proxyd.c
  5. 16s及宏基因组测序公司资源--20161104
  6. 【python】——小程序之电话薄
  7. linux(Ubuntu)安装QQ2013
  8. tomcat启动出错(转)
  9. bootstrap学习起步篇:初识bootstrap之html5语法构建hello篇(一)
  10. 一个不错的图片滑动展示插件 anythingslider
  11. container_of宏剖析
  12. Windows通用应用平台
  13. JDBC开发
  14. 入门系列之使用Sysdig监视您的Ubuntu 16.04系统
  15. 红警大战JAVA简单版
  16. iOS——调试工具LLDB学习
  17. 软件测试第二次作业:初识JUNIT单元测试方法
  18. java.lang.RuntimeException: Cannot create a secure XMLInputFactory 异常处理
  19. js实现往数组中添加非存在的对象,如果存在就改变键值。
  20. 获取Methods成员方法类

热门文章

  1. Day3-T4
  2. springboot (2.0以上)连接mysql配置
  3. 手把手教你用Python实现“坦克大战”,附详细代码!
  4. 转:JS高级学习笔记(8)- JavaScript执行上下文和执行栈
  5. LIS是什么?【质量控制】
  6. Mac下使用Hexo搭建个人博客
  7. Windows桌面图标不见了,可能是结束了explorer.exe进程导致
  8. ES6的一些语法
  9. (2)MongoDB副本集自动故障转移全流程原理
  10. 吴裕雄--天生自然 PHP开发学习:While 循环