java 中modCount 详解及源码分析

 更新时间:2017年02月04日 10:53:15   作者:魏福成  
这篇文章主要介绍了java 中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,保证线程之间修改的可见性。

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

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

相关文章

  • Java中线程中断的几种方法小结

    Java中线程中断的几种方法小结

    在Java中,线程中断是一种协作机制,它通过设置线程的中断标志位来通知线程需要中断,本文主要介绍了Java中线程中断的几种方法小结,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • 详解jvm对象的创建和分配

    详解jvm对象的创建和分配

    这篇文章主要介绍了jvm对象的创建和分配的相关资料,帮助大家更好的理解和学习使用Java,感兴趣的朋友可以了解下
    2021-03-03
  • Java Spring MVC获取请求数据详解操作

    Java Spring MVC获取请求数据详解操作

    Spring MVC 是 Spring 提供的一个基于 MVC 设计模式的轻量级 Web 开发框架,本质上相当于 Servlet,Spring MVC 角色划分清晰,分工明细。由于 Spring MVC 本身就是 Spring 框架的一部分,可以说和 Spring 框架是无缝集成
    2021-11-11
  • 基于Java实现获取本地IP地址和主机名

    基于Java实现获取本地IP地址和主机名

    这篇文章主要介绍了基于Java实现获取本地IP地址和主机名,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • 如何使用MyBatis Plus实现数据库curd操作

    如何使用MyBatis Plus实现数据库curd操作

    MyBatis-Plus是一个MyBatis 的增强工具,在MyBatis,的基础上只做增强不做改变,为简化开发、提高效率而生。 这篇文章主要介绍了MyBatis Plus实现数据库curd操作,需要的朋友可以参考下
    2021-09-09
  • java实现图片任意角度旋转

    java实现图片任意角度旋转

    这篇文章主要为大家详细介绍了java实现图片任意角度旋转,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-04-04
  • SpringBootAdmin+actuator实现服务监控

    SpringBootAdmin+actuator实现服务监控

    这篇文章主要为大家详细介绍了SpringBootAdmin+actuator实现服务监控,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • MultipartFile文件判断是否存在的操作

    MultipartFile文件判断是否存在的操作

    这篇文章主要介绍了MultipartFile文件判断是否存在的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • 基于SpringBoot和Vue实现分片上传系统

    基于SpringBoot和Vue实现分片上传系统

    最近想做一个关于文件上传的个人小网盘,一开始尝试使用了OSS的方案,但是该方案对于大文件来说并不友好,所以开始尝试分片上传方案的探索,接下来小编给大家详细的介绍一下如何基于SpringBoot和Vue实现分片上传系统,需要的朋友可以参考下
    2023-12-12
  • JavaWeb中Servlet的生命周期及线程安全问题详解

    JavaWeb中Servlet的生命周期及线程安全问题详解

    这篇文章主要介绍了JavaWeb中Servlet的生命周期及线程安全问题详解,Servlet 生命周期可被定义为从创建直到毁灭的整个过程,Servlet体系结构是建立在Java多线程机制之上的,它的生命周期是由Web容器负责的,需要的朋友可以参考下
    2024-01-01

最新评论