ConcurrentHashMap和HashMap的区别 小记

在提到ConcurrentHashMap和HashMap之前,要先从散列表(哈希表)开始。

        散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。简单来说就是存放了一个函数y=f(x),x为存放的键值,经过计算能获得我们需要的键值y。

        由于散列表是通过散列函数来将key值映射到表中的某一个位置,散列函数能使对一个数据序列的访问过程更加迅速有效,通过散列函数,数据元素将被更快地定位,所以其查询的时间速度可以认为是O(1)。

HashMap

        HashMap是Java集合框架中的一种实现类,它基于哈希表的数据结构来存储和管理元素。

通过查询可得知:

  • 在 Java 7 中使用的是 “数组 + 链表”,发生散列冲突的键值对会用头插法添加到单链表中;
  • 在 Java 8 中使用的是 “数组 + 链表 + 红黑树”,发生散列冲突的键值对会用尾插法添加到单链表中。如果链表的长度大于 8 时且散列表容量大于 64,会将链表树化为红黑树。在扩容再散列时,如果红黑树的长度低于 6 则会还原为链表;

在 java 8中引入红黑树能使得在散列冲突时提高查询速度,通过使用树的结构将查询的时间复杂度从O(n)变成O(logn)。

ConcurrentHashMap

        ConcurrentHashMap,并发的HashMap,JDK为我们提供了一个在并发环境下使用的线程安全的HashMap。在ConcurrentHashMap中,无论是读操作还是写操作都能保证很高的性能:在进行读操作时几乎不用加锁,而在写操作时通过锁分段技术,将整个哈希表分成多个(Segment),每个段都有自己的锁,不同的线程可以同时对不同的段进行操作,从而提高并发性能。

区别:

        线程安全性:

        ConcurrentHashMap和HashMap最明显的区别就是线程安全性问题。ConcurrentHashMap是线程安全的,而HashMap不是。在多线程环境下,由于HashMap的元素无序性,遍历结果的顺序是不确定的,多个线程同时对HashMap进行修改可能会导致数据不一致或者抛出并发修改异常。而ConcurrentHashMap使用了锁分段技术,在进行并发修改时可以保证线程安全性。所以在高并发环境下,HashMap会存在性能问题。

        键值:

        HashMap允许存储一个null键和多个null值,但需要注意,如果使用null作为键进行查找操作,可能会导致NullPointerException。

        与HashMap不同,ConcurrentHashMap不允许存储null键和null值。如果尝试将null键或null值放入ConcurrentHashMap,会抛出NullPointerException。

        迭代器:

        查得:

        ConcurrentHashMap的迭代器是弱一致性的,即它可以能够反映出迭代器创建之后发生的修改,但不保证将来的更改可见。

        而HashMap的迭代器是快速失败的,即在迭代器创建之后,如果其他线程对HashMap进行结构上的修改,会立即抛出ConcurrentModificationException异常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值