ConcurrentHashMap如何保证并发安全

ConcurrentHashMap简介:一款线程安全的HashMap类集合,底层数据结构采用Node数组 + 链表 /红黑树。java1.7采用Segement(基于ReetrantLock实现)分段锁解决并发安全,java1.8采用CAS + synchronized解决并发安全;java1.8采用CAS + synchronized是为了提高并发性能,CAS保证在需要放入数组元素且数组对应下标元素为null情况下无阻塞尝试放入元素,当需要放入数组元素且对应下标不为null时采用synconized只对首节点加锁,锁粒度相比1.7更小,只要hash不冲突就不会加锁,而且java1.6开始synconized进行了锁优化,并发效率进一步提升。

1.ConcurrentHashMap中线程安全的方法:

①putVal()方法放入一个元素

②replaceNode()方法

③clear()方法

④initTable()方法

⑤addCount()方法

重点是putVal()、initTable()和addCount()方法

putVal()方法源码:

final V putVal(K key, V value, boolean onlyIfAbsent) {
        //ConcurrentHashMap要求key和value均不为空
        if (key == null || value == null) throw new NullPointerException();
        //通过spread()方法获取key的hash
        int hash = spread(key.hashCode());
        //记录数组某一个下标包含的元素个数(以便最后进行树化的判断)
        int binCount = 0;
        //自旋加锁
        for (Node<K,V>[] tab = table;;) {
            Node<K,V> f; int n, i, fh;
            //判断Node数组是否需要初始化
            if (tab == null || (n = tab.length) == 0)
                tab = initTable();
            //(n - 1) & hash得到数组下标,tabAt()方法获取此下标元素,判断是否为空
            else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
                //该下标元素位空,尝试使用CAS放
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值