博客
关于我
Java——Java基础之ConcurrentHashMap
阅读量:336 次
发布时间:2019-03-04

本文共 2018 字,大约阅读时间需要 6 分钟。

put 方法

put 操作是 ConcurrentHashMap 中最常见的操作之一。在 putVal 方法中,如果发现当前线程的 hash 碰撞(即当前 hash 值对应的槽位已经有值),并且该值为 -1(表示 MOVED),那么说明 Map 正在扩容。此时,helpTransfer 方法会被调用以协助扩容,以加快扩容速度。


transfer 扩容方法

transfer 方法负责将 Map 的元素从当前表中扩展到更大的表中。当 Map 的当前表已达到扩容阈值时,transfer 方法会被调用。具体来说:

  • 通过 resizeStamp 方法获取当前表的长度。
  • 如果 sizeCtl 的低 16 位不等于 resizeStamp,或者 sizeCtl 已经超过了阈值,或者 nextTable 为空,或者 transferIndex 小于等于 0,则终止扩容。
  • 如果可以帮助扩容(即 sizeCtl 小于阈值),则将 sizeCtl 加 1,表示有多个线程在协助扩容。
  • 如果不在协助扩容,则将 sizeCtl 更新为 resizeStamp + 2,表示当前线程将独立进行扩容。

  • helpTransfer 帮助扩容方法

    helpTransfer 方法的主要作用是协助扩容。当 putVal 方法检测到当前 hash 碰撞(槽位已存在且值为 MOVED)时,会调用 helpTransfer 方法。该方法通过 fullAddCount 方法进行扩容操作。


    size 方法 / mappingCount 方法

    ConcurrentHashMap 的 size 方法返回当前 Map 中键值对的数量,但其最大值为 Integer.MAX_VALUE。由于 Map 的实际数量可能超过 Integer.MAX_VALUE,JDK 建议使用 mappingCount 方法代替 size 方法。

    public int size() {    long n = sumCount();    return ((n < 0L) ? 0 :             (n > (long)Integer.MAX_VALUE) ? Integer.MAX_VALUE :             (int)n);}public long mappingCount() {    long n = sumCount();    return (n < 0L) ? 0L : n;}

    sumCount 方法

    sumCount 方法用于统计 Map 中键值对的总数量。它通过遍历 counterCells 数组,累加每个 CounterCell 的 value。具体流程如下:

  • 初始化 sum 为 baseCount。
  • 如果 counterCells 不为空,则遍历 counterCells 数组,累加每个 cell 的 value 到 sum 中。
  • 返回 sum。

  • put 方法

    put 方法用于将键值对插入 Map 中。它会调用 putVal 方法,并在成功插入后调用 addCount 方法来更新计数器。

    public V put(K key, V value) {    return putVal(key, value, false);}final V putVal(K key, V value, boolean onlyIfAbsent) {    // ...(内部逻辑)    addCount(1L, binCount);    return null;}

    addCount 方法

    addCount 方法用于更新 Map 的计数器。它通过 CAS 操作尝试直接更新 baseCount。如果 CAS 操作失败,则通过 fullAddCount 方法进行批量更新。

  • 如果 counterCells 为空或 baseCount 更新失败,则执行 fullAddCount 方法。
  • fullAddCount 方法会递增 binCount,直到操作成功。

  • 扩容逻辑

    当 Map 达到扩容阈值时,sizeCtl 会被更新为负值,表示需要扩容。具体流程如下:

  • 通过 resizeStamp 方法获取当前表的长度。
  • 如果 sizeCtl 的低 16 位不等于 resizeStamp,或者 sizeCtl 已经超过了阈值,或者 nextTable 为空,或者 transferIndex 小于等于 0,则终止扩容。
  • 如果可以帮助扩容(即 sizeCtl 小于阈值),则将 sizeCtl 加 1,表示有多个线程在协助扩容。
  • 如果不在协助扩容,则将 sizeCtl 更新为 resizeStamp + 2,表示当前线程将独立进行扩容。

  • 通过以上方法,ConcurrentHashMap 实现了高效的线程安全 Map,能够在多线程环境下保持良好的性能。

    转载地址:http://wmeh.baihongyu.com/

    你可能感兴趣的文章
    python前端之css
    查看>>
    Python制作进度条,原来有这么多方法
    查看>>
    Python制作简单的学生成绩管理系统
    查看>>
    python制作甘特图的基本知识(附Demo)
    查看>>
    python制作一个简单的服务器,【Python】 做一个简单的 http 服务器
    查看>>
    Python到底能做什么?它的优点在哪?
    查看>>
    python利用pytorch库导出图像分割算子
    查看>>
    python利用pyshark监听网卡来抓包其中pyshark中摸索的一些可用参数
    查看>>
    python利用excel分析过杀漏失
    查看>>
    python判断汉字数目
    查看>>
    python判断文件是空的,如果是空的,就删除
    查看>>
    python判断密码是否正确_python密码判断是否符合要求的方法
    查看>>
    python判断字符串包含中文_Python 判断字符串是否包含中文
    查看>>
    python删除第一行_Python 乱码指北:一行删掉根目录
    查看>>
    Python删除列表元素的三种方法
    查看>>
    python初步学习-python数据类型-集合(set)
    查看>>
    python列表生成字典_Python中将字典转换为列表的方法
    查看>>
    python列表对应元素合并为列表及判断一个列表是几维
    查看>>
    python列表去重复后按照顺序_从包含不可共元素的Python列表中删除重复元素,同时保留顺序?...
    查看>>
    python列表前几个_python之列表
    查看>>