关于HashMap的一些深入探索与理解

在java中,大家几乎是离不开对集合的使用的,像Map系列,List系列,Set系列,但是很多人没有了解过或者研究过这些集合类到底可以用在什么地方,并且有什么注意的地方,因此本文分Map系列和List系列以及Set系列来讲述集合背后的故事。

一,HashMap

  1. HashMap的初始化容量是16,载入因子是0.75

  2. HashMap的key和value都可以为null

  3. HashMap的最大容量为1<<30

  4. HashMap是线程不安全的,HashMap判断线程不安全的方式是通过两个模数即modCount和HashIterator内部类的exceptedModCount是否相等来判断是否是出于多线程读写状态,如果不相等,则抛出ConcurrentModificationException异常,其中modCount在1.7以前的版本都是用volatile修饰的,但是从1.7开始就把这个修饰符去掉了,因为modCount是在修改了HashMap的结构之后加1,即modCount++,而大家都知道,volatile在多线程环境下无法保证原子性,因此1.7去掉这个修饰符也减少了一些性能损耗,至于如何确保并发无误,就可以用Collections.synchronizedMap和ConcurrentHashMap了。

二,Collections.synchronizedMap和ConcurrentHashMap线程安全的区别

大家都知道这两个都是确保使用Map时的线程安全方案,但是这两者又有什么区别,他们真的能够保证线程安全吗?

  1. Collections.synchronizedMap方法是集合类Collections中的一个静态类,这个SynchronizedMap实现了Map和serializable接口,它的每个方法都是使用synchronized来达到同步的,但是查看源代码之后你会发现,当你调用了entrySet()方法之后,再从这个entrySet()方法返回Iterator迭代器,然后使用迭代器在多线程来remove()时,也会出现并发问题,为什么呢,因为这个iterator是Set接口的迭代器,跟这个静态类是没有关系了,这样也将导致会出现并发问题而抛出同步异常

  2. ConcurrentHashMap实现了AbstractMap抽象类和ConcurrentMap接口,这个类的同步是由JVM的底层代码来负责同步处理的,前面说过modCount,在这个同步类中也有modCount,但是它在这个类的HashIterator中没有用到,而是使用Unsafe的锁管理机制来迭代数据的,因此保证了数据的线程安全

  3. 通过以上对二者的描述,可以知道,如果在多线程换进下确保不使用迭代器的情况下,二者都是可以使用的,但是如果使用迭代器,则只能选择ConcurrentHashMap类来实现,推荐在多线程条件下,都使用ConcurrentHashMap,这样避免造成以后的尴尬......

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值