并发编程(五)并发容器及原理分析

并发容器及原理分析

-- 1、KV集合HashMap的实现原理

1、HashMap的数据结构

2、HashMap的存取实现

什么是HashMap

HashMap是存储Key-Value键值对的集合

回忆一下SynchronousQueue在线程池的用途和场景

HashMap数据结构

table

Node节点数组

entrySet

HashMap.Node的Set集合

size

HashMap集合中元素的个数

modCount

标记HashMap修改的次数,每次调用put和clear方法,modCount会增加

threshold

当size大于threshold,就需要扩容,threshold默认为数组长度*loadFactor

loadFactor

加载因子,默认是0.75

HashMap.Node数据结构

hash

key.hashCode()经过移位计算后得到的值

key

HashMap要存储的键,通过key来获取值

Value

HashMap要存储的值

next

指向下一个Node节点

HashMap数据结构

HashMap存取实现

 

思考

请阅读HashMap的源码,看resize()方法是怎么实现的?

-- 2、HashMap在高并发场景下死循环分析

1、HashMap的扩容过程

2、并发情况下HashMap为什么会出现死循环问题

HashMap put过程

HashMap扩容过程

   /**

     * Transfers all entries from current table to newTable.

     */

    void transfer(Entry[] newTable, boolean rehash) {
        int newCapacity = newTable.length;
        for (Entry<K,V> e : table) {
            while(null != e) {
                Entry<K,V> next = e.next;
                if (rehash) {
                    e.hash = null == e.key ? 0 : hash(e.key);
                }
                int i = indexFor(e.hash, newCapacity);
                e.next = newTable[i];
                newTable[i] = e;
                e = next;
            }
        }
    }

                                                                                                 JDK7扩容实现

HashMap在无并发场景下扩容

                                                                      注:JDK7实现

 

HashMap在并发场景下扩容

线程一在transfer()中的这行代码被挂起

Entry<K,V> next = e.next;

线程二在线程一挂起后执行完自己的transfer()流程

HashMap读请求获取keyHash=9数据

思考

HashMap在并发场景下除了发生死循环,还会有哪些问题发生?

-- 3、ConcurrentHashMap的高并发实现原理

1、ConcurrentHashMap的数据结构

2、ConcurrentHashMap的并发处理思路

ConcurrentHashMap 数据结构

Segment类分析

  1. Segment集成ReentrantLock,具有加锁解锁的功能,segments有多少个元素,说明就有多少把锁,扮演了分段锁,降低并发竞争度
  2. 只有写才会对对应的Segment加锁,读不加锁

思考

ConcurrentHashMap中多出Unsafe类来获取对应字段值,这样的好处是什么?

-- 4、CopyOnWriteArrayList如何实现线程安全

1、为什么需要CopyOnWriteArrayList?

2、CopyOnWriteArrayList的线程安全实现

3、CopyOnWriteArrayList的使用场景

注:

回忆一下SynchronousQueue在线程池的用途和场景

为什么需要CopyOnWriteArrayList?

 

运行后输出报错信息:

java.util.ConcurrentModificationException

at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)

at java.util.ArrayList$Itr.next(ArrayList.java:859)

阅读源码发现:

ArrayList当读写线程同时运行时,使用fast-fail机制,抛出ConcurrentModificationException异常

ArrayList在读写线程同时运行时,无法满足开发者需求

改用CopyOnWriteArrayList后:

读写同时进行时,不会抛出ConcurrentModificationException异常

CopyOnWriteArrayList实现原理

添加元素

遍历元素

取元素

CopyOnWriteArrayList优缺点分析

优点

线程安全,可以兼容读写并发

缺点

耗内存(写时复制)

数据实时性不高,可能获取到旧数据

CopyOnWriteArrayList使用场景

读多写少,如白名单黑名单等

集合数量不大

数据要求不是强实时

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

plenilune-望月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值