java基础之 Map

HashMap

数组加链表结构,数组初始容量为16,负载因子为0.75,扩容阀值为容量*负载因子或默认容量最大值+1,每次扩容2倍,如果扩容量达到最大可扩容量后,扩容阀值改为整型最大值,不再进行扩容。线性不安全,体现在需要扩容时使用头插法重新计算拷贝节点数据,多线程同时执行transfer方法可能导致同Hash的数组节点链表变成循环链表,当查询一个不存在的键值时如果命中该hash节点将导致死循环。多线程读写无锁的HashMap时可能会由于线程间的不可见性造成读取脏数据。ConcurrentHashMap使用final字段与volatile关键字修饰值对象与下一个引用对象,使得读操作不需要加锁。

LinkedHashMap

继承HashMap,数据结构采用hash表+链表方式,重写了HashMap添加元素得方法,增加了双向链表的维护。

TreeMap

红黑树数据结构,二叉树有序,可以传入自定义比较器排序,可以获取一段范围内的数据。

HashTable

所有读写方法都加了synchronized关键字修饰,线性安全但性能极低。

ConcurrentHashMap

采用分段锁技术,对每个segment的修改操作加锁,不同segment之间没有锁,因此不同segment之间支持并发操作。ConcurrentHashMap无读锁,响应的值对象与链表下一个对象使用volatile关键字修饰,保证线程间共享变量的可见性。初始化默认segments数量为16,segment 内部entry数量初始值为2(jdk 1.7),负载因子为1f(segment[0]为0.75f).segments初始化完成后数量不再发生变化,segments数量即为最大可支持并发修改线程数。ConcurrentHashMap put值写入同一segment时进行加锁。当元素数量达到阀值时进行rehash扩容,该方法与HashMap transfer操作类似,需要扩容的是Segment内部HashEntry数组大小。ConcurrentHashMap put操作,通过hash计算出segment下标位置。再通过hash put进segment的HashEntry hash表中,get类似。size()操作通过两次相加各个segment对象总数并比较是否sum相同,如果不相等说明当前有元素数量已被修改。不相等则全部segmnet加锁重新计算。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值