HashMap与ConcurrentHashMap

HashMap:数组+链表

真正存放数据的地方:

Entry<K,V>[] table = (Entry<K,V>[]) EMPTY_TABLE

初始化的大小 1<<4

最大值 1<<30

默认负载因子 0.75

扩容涉及到rehash 复制数据等操作,非常消耗性能。

jdk1.7
当Hash冲突严重时,在桶上形成的链表会变得原来越长,这样查询时的效率就会越来越低,时间复杂度O(n)。

Jdk1.8

红黑树 TREEIFY_THRESHOLD 用于判断将链表转换为红黑树的阈值。

HashEntry 修改为Node

红黑树提高了查询效率 提高到了O(logn)

建议这样取值:

Iterator<Map.Entry<String, Integer>> entryIterator = map.entrySet().iterator();
while (entryIterator.hasNext()) {
     Map.Entry<String, Integer> next = entryIterator.next();
     System.out.println("key=" + next.getKey() + " value=" + next.getValue());
}

ConcurrentHashMap:数组+链表 解决并发问题

由Segment数组、HashEntry组成

数组+链表

存放数据时首先需要定位到具体的Segment中。

ConcurrentHashMap支持CurrencyLevel(Segment数组数量)的线程并发。

将key通过Hash 之后定位到具体的Segment,再通过一次Hash定位到具体的元素上。

HashEntry中的value用volatile修饰,确保可见性。

JDK1.7存在的问题:遍历链表效率太低

JDK1.8 采用了CAS+synchronized来保证并发安全性。

存放数据的HashEntry 改为Node。

用红黑树查询效率O(logn)

取消了ReentrantLock 改为了 synchronized

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值