HashMap 与 ConcurrentHashMap(jdk1.8)

HashMap的实现

HashMap存储的是key-value的键值对,允许key为null,也允许value为null。HashMap内部为数组+链表的结构。在JDK1.6,JDK1.7中,HashMap采用数组+链表实现。默认情况下,HashMap 初始容量是16,负载因子为 0.75。

HashMap中数据结构优缺点:

数组

数组存储区间是连续的,占用内存严重,故空间复杂的很大。但数组的二分查找时间复杂度小,为O(1);数组的特点是:寻址容易,插入和删除困难;

链表

链表存储区间离散,占用内存比较宽松,故空间复杂度很小,但时间复杂度很大,达O(N)。链表的特点是:查找困难,插入和删除容易。

而JDK1.8中,HashMap采用位桶+链表+红黑树实现,当链表节点较少时仍然是以链表存在,当链表节点较多时(大于8)会转为红黑树。 

转为红黑树节点后,链表的结构还存在,通过next属性维持,红黑树节点在进行操作时都会维护链表的结构,并不是转为红黑树节点,链表结构就不存在了。

链表中移除一个节点只需如下图操作,其他操作同理。

红黑树在维护链表结构时

定位哈希桶数组索引位置

// 代码1
static final int hash(Object key) { // 计算key的hash值
    int h;
    // 1.先拿到key的hashCode值; 2.将hashCode的高16位参与运算
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
// 代码2
int n = tab.length;
//3. 将(tab.length - 1) 与 hash值进行&运算
int index = (n - 1) & hash;

 

ConcurrentHashMap

ConcurrentHashMap 是concurrent包下的一个集合类。它是线程安全的哈希表。它是通过“分段锁”来实现多线程下的安全问题。它将哈希表分成了不同的段内使用了可重入锁(ReentrantLock ),不同线程只在一个段内存在线程的竞争。它不会对整个哈希表加锁。

HashMap线程不安全,在高并发情况下会产生死锁。HashMap的get方法缺乏读一致性,一个读线程和一个写线程同时对Key A的值进行操作,会导致读取结果为旧值。

HashTable线程安全,高并发情况下会锁定整个map表,其他线程则不 能去访问该map表,效率低下。

在Java7中,ConcurrentHashMap由Segment数组结构和HashEntry数组组成。

Segment(分段锁) ,ConcurrentHashMap中的分段锁称为Segment,相当于一个数组,数组中的每个元素又是一个链表,同时又是一个ReentrantLock(Segment继承了ReentrantLock)。 ConcurrentHashMap使用分段锁技术,将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问,能够实现真正的并发访问,提高效率。

在Java8中,ConcurrentHashMap去除了Segment分段锁的数据结构,主要是基于CAS(Compare And Swap,比较交换)操作保证保证数据的获取以及使用synchronized关键字对相应数据段加锁实现了主要功能,这进一步提高了并发性。同时为了提高哈希碰撞下的寻址性能,Java 8在链表长度超过一定阈值时将链表转换为红黑树。

 

ConcurrentHashMap与HashMap、HashTable的区别

1.ConcurrentHashMap和HashMap是2k扩容,HashTable扩容:2k+1;
2.ConcurrentHashMap 、HashTable线程安全;HashMap线程不安全;
3.ConcurrentHashMap 、HashTable不允许值为null,值为null时抛出异常,
HashMap允许值为null;
4.ConcurrentHashMap在jdk1.8中底层用的是synchronized+CAS+HashEntry+红黑树。
5.HashTable所有方法都加锁synchronized。当一个线程来访问时候,会锁定整个map表,其他线程则不 能去访问该map表;
ConcurrentHashMap采用了CAS+同步锁Synchronized对链表中Node<k,V>节点进行锁定;当一个线程访问时候,会锁住该Node节点,而其他线程过来若访问其他节点时候不影响,可以正常访问;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值