当前位置: 首页 > article >正文

【Java EE】-多线程编程(十) HashMapHashTableConcurrentHashMap之间的区别

作者:学Java的冬瓜
博客主页:☀冬瓜的主页🌙
专栏:【JavaEE】
分享
主要内容:HashMap和HashTable之间的区别、HashTable和ConcurrentHashMap之间的区别、

文章目录

  • 一、HashMap和HashTable的区别
  • 二、HashTable和ConcurrentHashMap之间的区别
    • 1、最大的优化之处:ConcurrentHashMap比HashTable大大降低了锁冲突
    • 2、ConcurrentHashMap只对写加锁 并使用volatile+原子的修改提高性能
    • 3、ConcurrentHashMap内部使用了大量的CAS,从而提高并发效率
    • 4、ConcurrentHashMap扩容使用"慢慢搬"的策略

一、HashMap和HashTable的区别

HashMap是线程不安全的
而HashTable是线程安全的,因为HashTable所有方法都加上了synchronized,是串行(同步的)。

二、HashTable和ConcurrentHashMap之间的区别

1、最大的优化之处:ConcurrentHashMap比HashTable大大降低了锁冲突

我们知道哈希表可以使用闭散列(开放地址法)和开散列(链地址法)解决哈希冲突,但是一般都是使用链地址法,也称为哈希桶。
哈希桶是使用数组 + 链表的方式组织起来。

对于HashTable来说,它的加锁是直接加上一个大锁,把整个数组+链表的操作用一把锁加锁,这会导致性能问题。比如多个线程修改一个链表上的数据时,会有线程安全问题,所以一个线程先修改,其它线程阻塞等待,这时候是没毛病的;但是如果是多个线程修改不同链表上的节点时,因为不可能找到同一个节点,没有线程安全问题,所以这个大锁就没必要加上了,加了锁,会有锁冲突,反而会降低效率。因此ConcurrentHashMap就给我们做了优化。

对于ConcurrentHashMap来说,相对于HashTable来说,ConcurrentHashMap减小了锁的粒度。在JDK1.7之前,它是使用"区间锁"(给几个链表加一个锁)的方式降低锁冲突,从而提高并发效率。在JDK1.8及之后,就给每个链表加上锁,这样就可以完美解决使用HashTable时的线程安全问题和性能问题。

2、ConcurrentHashMap只对写加锁 并使用volatile+原子的修改提高性能

HashTable是对每个方法都加锁

ConcurrentHashMap不对读加锁,只针对写加锁。
但是这样的话,多线程读没问题;多线程写,因为加锁了,无线程安全问题;多线程读和写,就有线程安全问题,可能会出现类似"脏读"的问题。
因此ConcurrentHashMap就再加上了另外一个策略:volatile和写操作原子。

3、ConcurrentHashMap内部使用了大量的CAS,从而提高并发效率

Concurrent内部充分利用了CAS,削减锁操作,从而提高效率

4、ConcurrentHashMap扩容使用"慢慢搬"的策略

在HashMap和HashTable中,插入元素,在某一次put操作,当达到扩容的条件时,会重新申请一个空间,然后把旧数组中的每个元素一个一个重新哈希转移到新数组这里。也就是说,如果数据量很大很大时,会可能存在在某一次put时,会卡一段时间的问题。

而ConcurrentHashMap对上面的场景做了优化,它使用 “慢慢搬” 的策略,即插入元素,在某一次put操作时,满足扩容条件时,先申请一个数组空间,然后先把旧数组中的元素 “搬一些” 到新数组,在每次put的时候都 “搬一点”,如果在 “搬运元素” 期间,需要get操作取数据,就从旧数组和新数组中都找。直到最后一次put时,元素 “搬运” 完,旧的数组 + 链表的全部元素都重新哈希到新的数组 + 链表的结构当中了。


http://www.kler.cn/news/10308.html

相关文章:

  • chapter-1数据管理技术的发展
  • 私有化部署VideoTogether一起看视频
  • 微积分——极值定理的证明
  • Jetson nano部署剪枝YOLOv8
  • 技术分享 | observer 资源水位介绍
  • Java多线程面试题
  • GEE:支持矢量机(SVM)分类教程
  • 基于JSP的网上购物系统的设计与实现(论文+源码)_kaic
  • 业务项目管理软件使用推荐
  • java day4
  • js读取fetch的返回值
  • Linux ln 命令
  • 运行时内存数据区之程序计数器
  • 【Vite】对 CSS 处理
  • Excel技能之数据验证,总有一款适合你
  • BGP策略实验
  • RPC调用框架简单介绍
  • 心累,网站被盗刷 1.7T 流量
  • vue中的pinia使用和持久化 - 粘贴即用
  • Unity之获取游戏物体对象或组件的几个方法
  • JVM/GC/G1
  • SpringBoot与RabbitMQ 集成以及死信队列,TTL,延迟队列
  • 为什么要创建FAQ?这篇文章告诉你
  • vue3中的全局防抖节流指令
  • Vue学习——【第五弹】
  • 【权限维持】域控后门SSPHOOKDSRMSID万能钥匙
  • 能聊天、会学习,远不是GPT的终局
  • Android—IMS的InputReader
  • 单片机程序是如何运行起来
  • python+vue+ 疫情冷链追溯管理系统