Java源码解析ConcurrentHashMap的初始化

 更新时间:2019年01月08日 11:50:45   作者:李灿辉  
今天小编就为大家分享一篇关于Java源码解析ConcurrentHashMap的初始化,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

首先看一下代码

private final Node<K,V>[] initTable() {
    Node<K,V>[] tab; int sc;
    while ((tab = table) == null || tab.length == 0) { // 第一次检查
      if ((sc = sizeCtl) < 0)
        Thread.yield(); // lost initialization race; just spin
      else if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {
        try {
          if ((tab = table) == null || tab.length == 0) {// 第二次检查
            int n = (sc > 0) ? sc : DEFAULT_CAPACITY;
            @SuppressWarnings("unchecked")
            Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n];
            table = tab = nt;
            sc = n - (n >>> 2);
          }
        } finally {
          sizeCtl = sc;
        }
        break;
      }
    }
    return tab;
  }

ConcurrentHashMap在初始化时,如何进行多线程间的同步?

ConcurrentHashMap在初始化时,首先会判断,哈希表是否已经初始化了。如果没有,则尝试进行初始化。

首先会判断sizeCtl的值。sizeCtl是用于多线程之间同步的一个互斥变量。当sizeCtl < 0时,表示已经有线程正在初始化哈希表或哈希表正在扩容,此时,不能再进行操作。

此处sizeCtl其实是实现了自旋锁的功能。自旋锁,即,获取锁失败时,让出CPU,稍后再进行尝试,重复这个过程,直到获得到锁为止。让出CPU的动作,是通过java中的Thread.yield()来实现的。在学校学习java的时候曾经接触过线程的这个方法,但当时不明白什么场景下会用到。原来,Thread.yield()方法可以用来实现自旋锁。

这里,可以提出一个问题,自选锁方式和死循环方式来判断sizeCtl的值,有什么不同?

当然是效率的不同。死循环时,程序会频繁读取sizeCtl的值,在满足条件之前,会浪费很多CPU周期。而自选锁的效率更高,因为当它判断sizeCtl不满足条件时,会主动让出CPU,此时,当前线程会处于ready状态,等待下一次被处理器选中并执行的机会。在这段时间里,其他的线程得以利用CPU周期。所以,自旋锁的效率更高。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。如果你想了解更多相关内容请查看下面相关链接

相关文章

  • SpringBoot整合Echarts实现用户人数和性别展示功能(详细步骤)

    SpringBoot整合Echarts实现用户人数和性别展示功能(详细步骤)

    这篇文章主要介绍了SpringBoot整合Echarts实现用户人数和性别展示,通过数据库设计、实现数据访问层、业务逻辑层和控制层的代码编写,以及前端页面的开发,本文详细地介绍了SpringBoot整合Echarts的实现步骤和代码,需要的朋友可以参考下
    2023-05-05
  • 运用java以及循环打印菱形详细实例代码

    运用java以及循环打印菱形详细实例代码

    最近在看算法书的时候,看到有打印上三角的算法,然后要举一反三,下面这篇文章主要介绍了运用java以及循环打印菱形的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-10-10
  • 浅谈Arrays.asList()方法的使用

    浅谈Arrays.asList()方法的使用

    本文主要介绍了Arrays.asList()方法的使用。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • 浅析Java集合中的LinkedHashSet

    浅析Java集合中的LinkedHashSet

    这篇文章主要介绍了浅析Java集合中的LinkedHashSet,LinkedHashSet 是 Java 中的一个集合类,它是 HashSet 的子类,并实现了 Set 接口,与 HashSet 不同的是,LinkedHashSet 保留了元素插入的顺序,并且具有 HashSet 的快速查找特性,需要的朋友可以参考下
    2023-09-09
  • Java中类的定义与实例化详解

    Java中类的定义与实例化详解

    这篇文章主要给大家介绍了关于Java中类的定义与实例化的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Java具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-11-11
  • java 基础教程之多线程详解及简单实例

    java 基础教程之多线程详解及简单实例

    这篇文章主要介绍了java 基础教程之多线程详解及简单实例的相关资料,线程的基本属性、如何创建线程、线程的状态切换以及线程通信,需要的朋友可以参考下
    2017-03-03
  • Java实现微信登录并获取用户信息功能(开发流程)

    Java实现微信登录并获取用户信息功能(开发流程)

    这篇文章主要介绍了Java实现微信登录并获取用户信息功能(开发流程),本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2024-07-07
  • java利用Calendar类打印日历

    java利用Calendar类打印日历

    这篇文章主要为大家详细介绍了java利用Calendar类打印日历,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07
  • java通过RESTful API实现两个项目之间相互传输数据

    java通过RESTful API实现两个项目之间相互传输数据

    一些特殊场景中,两个项目发布在不同的服务器,并且由于服务器限制特殊情况ip无法相通时进行开放接口方式进行数据传输,下面我们就来看看java通过RESTful API实现这一需求吧
    2025-09-09
  • 全面理解Java中的引用传递和值传递

    全面理解Java中的引用传递和值传递

    这篇文章主要介绍了全面理解Java中的引用传递和值传递,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10

最新评论