请选择 进入手机版 | 继续访问电脑版

ConcurrentHashMap

[复制链接]
三兄弟沙发谢洪江 发表于 2020-12-31 19:24:24 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
ConcurrentHashMap

数组 + 链表 +红黑树 的简朴梳理

初始化数组长度默认长度16,初始化有指定长度,就会返回指定长度(n)的数组

  1. private final Node[] initTable() {        Node[] 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[] nt = (Node[])new Node[n];                        table = tab = nt;                        sc = n - (n >>> 2);                    }                } finally {                    sizeCtl = sc;                }                break;            }        }        return tab;    }
复制代码
指定长度数组的盘算规则

  比指定长度initialCapacity大的最小的2的n次方
  1. tableSizeFor(initialCapacity + (initialCapacity >>> 1) + 1))
复制代码
盘算Key的Hash值

  1. int hash = spread(key.hashCode());
复制代码
添加一个Node节点

  i=(n - 1) & hash 数组长度和hash值 转成二进制后举行运算 同为1 就是1,否则为0
如果 数组 i 为空那么就会创建一个Node节点 无锁添加
如果 数组 i 不为空 那么就会为当前Node节点添加子节点 加锁添加
  1. if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {     if (casTabAt(tab, i, null,new ConcurrentHashMap.Node(hash, key,value, null)))         break;    }
复制代码
添加一个Node链表的子节点

  1、key的去重判断
  1. if (e.hash == hash &&      ((ek = e.key) == key || (ek != null && key.equals(ek)))) {        oldVal = e.val;        if (!onlyIfAbsent)             e.val = value;               break;  }
复制代码
  2、声明一个Node pred将他指向原先存在的Node 对象
  1. ConcurrentHashMap.Node pred = e;
复制代码
  3、 找到该Node链表节点下最后一个节点
  1. if ((e = e.next) == null)
复制代码
  4、最后添加链表节点
  1. pred.next = new ConcurrentHashMap.Node(hash, key,value, null);
复制代码
红黑二叉树添加

  1. if (f instanceof ConcurrentHashMap.TreeBin) {    ConcurrentHashMap.Node p;    binCount = 2;    if ((p = ((ConcurrentHashMap.TreeBin)f).putTreeVal(hash, key,value)) != null) {         oldVal = p.val;         if (!onlyIfAbsent)                 p.val = value;         }    }
复制代码
转换成红黑二叉树

  如果一个链表下的节点大于等于8 转换成红黑二叉树
  1. if (binCount >= TREEIFY_THRESHOLD)    treeifyBin(tab, i);      if (oldVal != null)          return oldVal;      break;   }
复制代码
来源:https://blog.csdn.net/Lihshan/article/details/111999353
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

发布主题

专注素材教程免费分享
全国免费热线电话

18768367769

周一至周日9:00-23:00

反馈建议

27428564@qq.com 在线QQ咨询

扫描二维码关注我们

Powered by Discuz! X3.4© 2001-2013 Comsenz Inc.( 蜀ICP备2021001884号-1 )