• ConsurrentHashMap InitTable 疑问与思考


    ConsurrentHashMap InitTable 疑问与思考

    ConsurrentHashMap 作为单机下经常使用的一个线程安全Map值得我们学习一下,以下其初始化的过程的代码,以及学习过程中遇到的疑惑与自己的思考

     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;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    1、多线程下该方法不加锁时如何保证线程安全的

    通常意义下的加锁,都是去检查一个东西是否被“其他”持有,如果被持有则本次加锁尝试失败。这里也是同样的思路,通过判断sc是否小于零来判断当前是否有其他线程操作,如果有其他线程操作到下面sc会被修改成**-1**来表示被加锁,同时CAS的操作保证了只能由一个线程修改成功,即只有一个线程能获得锁

    2、为什么使用while 而不是if

    initTable 的方法是为了完成初始化返回一个node数组,所以没有**“获取锁”线程需要陷入等待,等待其他线程完成初始化,所以该方法使用了while来让没有“获取锁”**的线程不断循环等待。

    3、为什么使用Thread.yield(),而不是return、sleep

    第二个问题说到需要循环等待所有自然不可能提前return,那为什么不用sleep,因为我们并不知道另一个线程什么时候完成初始化,也就不知道sleep多少秒,多了、少了都不合适,所以干脆就让出cpu时间片,等下一次再看看,如果其他线程完成了初始化就返回,否则重复以上。这其实就是源码中注释表达的含义:lost initialization race; just spin,退出竞争,不断自旋。

  • 相关阅读:
    高考计算机专业 热门专业方向
    零代码极限封装的【接口自动化测试框架】震碎你的三观
    react的动画
    原来 vue3 文件编译是这样工作的!看完后更懂vue3了
    树状数组基本操作
    数据结构-求关键路径和关键活动
    128 只 LED 显示驱动芯片 CH457
    realloc函数应用&IO泄露体验
    维态思(上海)环保科技有限公司 | 2024全国水科技大会暨技术装备成果展览会
    对于UDS协议的传输控制协议ISO15765的学习记录
  • 原文地址:https://blog.csdn.net/weixin_43779268/article/details/126025274