5.1Hashtable、HashMap和ConcurrentHashMap

5.1Hashtable、HashMap和ConcurrentHashMap

https://mp.weixin.qq.com/s/AixdbEiXf3KfE724kg2YIw

Hashtable和HashMap区别:

常用:

  • 1.Hashtable是线程安全的,HashMap则不是。Hashtable可以在多线程情况下使用。
  • 2.Hashtable效率低于Hashmap(因为Hashtable会对数据操作的时候都会上锁)
  • 3.Hashtable不允许键或值为null,HashMap允许键或值都可以为null

不常用:

  • 1.实现方式不同。
  • 2.初始化容量不同,Hashtable为11,HashMap为16,负载因子默认为0.75(当达到当前容量的75%开始扩容)
  • 3.扩容机制不同:Hashtable为n2+1(重新用hash值取模),HashMap为2n(因为HashMap使用的是位操作&,所以扩容效率更高)
  • 4.迭代器不同。

HashMap和ConcurrentHashMap区别:

JDK7中

ConcurrentHashMap用了Segment数组和HashEntry链表组成散列表。
HashEntry用volatile修饰Value和next(和HashMap的区别)

volatile的特性:

  • 1.可见性:不同线程对这个变量进行操作的可见性,即一个线程修改了某个变量的值,新值对其他线程来说是立即可见的
  • 2.有序性:禁止进行指令重排序。
  • 3.只能保证对单次读/写的原子性,不能保证i++这种操作
ConcurrentHashMap采用分段锁技术,不会像HashTable那样不管是put还是get都需要同步。
ConcurrentHashMap的put和get过程
put
  • 1.尝试自旋获取锁
  • 2.如果重试次数达到设定的最大值,改为阻塞锁获取
get(非常高效,整个过程不需要加锁)
  • 由于用volatile修饰,保证了内存可见性,所以每次都是最新值。
HashMap是数组+链表组成的散列表(JDK8中当链表长度超过8时改为红黑树)

JDK8中

ConcurrentHashMap抛弃原有的Segment分段锁,采用CAS+synchronied保证并发安全
ConcurrentHashMap将HashEntry改成了Node,把值和next采用volatile修饰,保证可见性,和HashMap一样引用了红黑树
ConcurrentHashMap的put操作
  • 1.根据key计算出hash值
  • 2.根据key定位Node,如果为空则用CAS写入,失败则自旋(不加锁,读取时记录原值,写回时再获取一次,与原值比较,如果一致则写入,如果不一致则重新读取)
  • 3.判断是否需要扩容
  • 4.如果都不满足,用synchronized锁写入数据
  • 5.判断是否转换为红黑树
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。