HashTable, HashMap, ConcurrentHashMap 总结

目录

一、HashMap

二、HashTable

三、ConcurrentHashMap

总结

一、HashMap

HashMap是Java中的一个数据结构,它实现了Map接口。HashMap通过一个哈希表来存储key-value键值对,并且支持高效地添加、删除和查找操作。在HashMap中,key和value可以为任何非空对象,而且可以为null。HashMap的特点包括:快速访问,高效的插入和删除,非线程安全。HashMap也是Java中最常用的集合之一。

  1. HashMap 的键值可以为null (当key为空时,哈希会被赋值为0)
  2. HashMap 的默认初始容量是16, 最大容量是2^30;
  3. HashMap 使用的数据结构是 数组 + 链表 + 红黑树
  4. HashMap 效率非常高,但线程不安全

二、HashTable

HashTable是Java中的一个数据结构,也实现了Map接口。它与HashMap相似,都是通过哈希表来存储键值对。然而,HashTable是线程安全的,它的各种操作都是同步的,可以避免并发操作带来的问题。相应地,HashTable的性能可能会受到影响,因为同步机制会引入一定的开销。HashTable的特点包括:线程安全、支持键值对的插入、删除和查找、key和value都不能为null。然而,由于HashTable的同步机制,建议在只有单线程访问的情况下使用HashMap。

  • HashTable 的键值不能为null
  • HashTable 虽然线程安全,但只是简单得用 synchronized 给所有方法加锁,相当于是对this加锁,也就是对整个HashTable对象进行加锁(非常无脑)

 

在多线程环境下,这种“无脑”的加锁方式是非常低效的:

  1. 多个线程访问同一个Hashtable对象时,无论做什么操作,都会产生锁冲突;
  2. 如果某个线程触发了扩容机制,那么就会由这个线程完成整个扩容过程,如果元素过多,效率则非常低,其它线程阻塞等待的时间也会更长。
  3. Java官方已经不推荐使用Hashtable了~
  4. 不涉及线程安全问题时使用HashMap,如果要保证线程安全就使用ConcurrentHashMap

三、ConcurrentHashMap

(1)锁粒度的控制

ConcurrentHashMap不是锁整个对象,而是使用多把锁,对每个链表(哈希桶)都进行加锁,只有当两个线程同时访问同一个链表时,才会产生锁竞争,因此极大地降低了锁冲突的概率。

 

(2)ConcurrentHashMap 只给写操作加锁,读操作没加锁

ConcurrentHashMap只对写操作进行加锁,读操作没有加锁,此时会有三种情况:

  1. 两个线程同时修改一个哈希桶时才会产生锁冲突;
  2. 两个线程同时读数据,不会有锁冲突;
  3. 一个线程修改,一个线程读,也没有锁冲突。
  4. 第三种情况可能会有线程不安全问题,这和我们写的代码有关,但是ConcurrentHashMap中的读操作使用了Volatile,来保证读到的数据不是修改了一半的数据。

(3)充分利用到了CAS的特性 

ConcurrentHashMap充分利用了CAS的特性,避免出现重量级锁的情况。

(4)扩容操作特殊优化

Hashtable的扩容机制是,创建一个更大的新数组,然后由一个线程一次性把旧数组中的元素搬运到新数组。因为如果数据量很大的时候,创建新数组将数据全部搬运过去,那么开销就会很大,所以为了解决这个问题 进行了这个优化

而ConcurrentHashMap则是让新数组和旧数组同时存在一段时间,在这期间,后续每个操作ConcurrentHashMap的线程都会负责搬运旧数组的一部分元素到新数组,直到搬运完旧数组的最后一个元素时,再把旧数组删除~

搬运期间,插入元素时直接插入到新数组中;查询元素时,新数组和旧数组一起查。


总结

HachMap和HashTable的区别

  1. HashMap线程不安全,HashTable线程安全。
  2. 包含的contains方法不同,HashMap是没有contains方法的。
  3. Hashmap是允许key和value为null值的。
  4. 计算hash值方式不同。
  5. .扩容方式不同。
  6. 解决hash冲突方式不同。
  7. HashMap是继承自AbstractMap类,而Hashtable是继承自Dictionary类。
  8. 对外提供的接口不同,Hashtable比HashMap多提供了elements() 和contains() 两个方法。
  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值