博客
关于我
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/

    你可能感兴趣的文章
    OKR为什么到今天才突然火了?
    查看>>
    ollama本地部署DeepSeek(Window图文说明)
    查看>>
    onCreate()方法中的参数Bundle savedInstanceState 的意义用法
    查看>>
    OneBlog Shiro 反序列化漏洞复现
    查看>>
    one_day_one--mkdir
    查看>>
    ONI文件生成与读取
    查看>>
    onlyoffice新版5.1.2版解决中文汉字输入重复等问题
    查看>>
    oobbs开发手记
    查看>>
    OPEN CASCADE Curve Continuity
    查看>>
    Open Graph Protocol(开放内容协议)
    查看>>
    Open vSwitch实验常用命令
    查看>>
    Open WebUI 忘了登入密码怎么办?
    查看>>
    open-vm-tools-dkms : 依赖: open-vm-tools (>= 2:9.4.0-1280544-5ubuntu3) 但是它将不会被安装
    查看>>
    Openbox-桌面图标设置
    查看>>
    opencart出现no such file or dictionary
    查看>>
    opencv Mat push_back
    查看>>
    opencv waitKey() 函数理解及应用
    查看>>
    OpenCV 中的图像转换
    查看>>
    OpenCV 在 Linux 上的 python 与 anaconda 无法正常工作.收到未实现 cv2.imshow() 的错误
    查看>>
    Opencv 完美配置攻略 2014 (Win8.1 + Opencv 2.4.8 + VS 2013)上
    查看>>