concurrenthashmap和hashtable多线程效率对比

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


一.hashmap、concurrenthashmap和hashtable线程安全性

hashmap是线程不安全的,concurrenthashmap和hashtable都是线程安全性的。写个程序验证一下。
在这里插入图片描述在这里插入图片描述
创建两个线程,两个线程各往同一容器中写入十万条数据,且key不存在重复。可以看到全部20万条数据成功落入hashtable和courrentHashMap,由此可见hashtable和courrentHashMap是线程安全的。而hashmap少了近三千条数据,故hashmap线程不安全。

二、hashmap为什么线程不安全?

hashmap中未引入任何锁机制,既没有使用synchronized关键字,也没有创建ReentrantLock类对象。那硬使用多线程操作hashmap会有什么问题。我们看看源码(hashmap源码在另篇博客HashMap底层原理及hashmap扩容中进行了详细解读)。
在这里插入图片描述
如果A线程先运行到629行,发现数组第5格是空,于是准备运行630行,即往数组第五格插入元素。但不巧这时候线程A挂起了,线程B开始运行,线程B也运行到629行,又不巧线程B的key和线程A的key存在hash冲突。于是线程B也发现第五格是空,并成功运行了第630行,即往数组第五格插入元素。然后线程B开始挂起,线程A开始运行。由于线程A已经判定第五格没有元素,而它也并不知道线程B已经往第五格中插入元素了。于是,线程A会继续运行第630行在数组第五格插入元素。结果就是线程B插入的元素就被线程A覆盖掉了。641行采用链式寻址法处理hash冲突也会遇到一样的问题。

三、hashtable多线程和courrenthashmap多线程效率对比

1.先比较单线程情况下两者效率

在这里插入图片描述
在这里插入图片描述
可以看到,单线程环境下写入一百万条数据hashtable是要远快于concurrentHashMap的。

2.再比较多线程情况下两者效率

创建十条线程,每个都往同一容器中写入十万条数据,比较hashtable和concurrenthashmap的速度。
在这里插入图片描述
在这里插入图片描述

可以看到,多线程下同样写一百万条数据,hashtable的速度比起单线程反而慢了近一倍。

在这里插入图片描述
在这里插入图片描述
而同样是多线程写一百万条数据,ConcurrentHashmap的速度相比单线程快了近三倍。

四、为什么hashtable多线程效率低

进hashtable源码可以发现hashtable实现多线程的方式非常简单粗暴,就是在每个方法都加上了synchronized关键字,synchronized关键字修饰非静态方法就意味着当一个线程访问了这个方法,其他线程都不能访问该方法。一核工作,九核围观。这样不仅提升不了多线程下程序运行速度,还会因为线程的切入切出导致资源的浪费,这就是为什么hashtable多线程下速度反而比单线程慢了。

在这里插入图片描述

五、为什么concurrenthashmap多线程效率高

在这里插入图片描述
可以看到concurrenthashmap对于锁的应用精准多了。以put方法举例,1014行用到了自旋锁,1019行用到了cas乐观锁,1027行用synchronized关键字修饰局部变量实现了分段锁。
1018行表示计算完hash值后最终确认的数组位置如果是空,进入1019行。
1019行代码表示给该数组位置插入元素前,判断一下是否有别的线程也在这个位置插入了数据,没有则插入节点跳出自旋,反之则不插入元素,进行自旋操作。
1025行之后均是处理hash冲突,其操作与hashmap类似,不同的是程序对于传入节点位于数组上的位置进行了上锁,也就是对桶上锁,使得同一时刻别的线程无法再操作这个数组位置。但数组的其他位置是能操作的。实现了分段锁。

六、总结

hashmap不支持多线程。hashtable虽然支持多线程但本身使用的重量级锁效率太低。而concurrenthashmap使用了乐观锁、自旋锁和分段锁,使得程序的整体效率大幅提高。

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值