ConcurrentHashMapHashtable的区别主要体现在实现线程安全的⽅式上不同。

  • 底层数据结构:JDK1.7 的ConcurrentHashMap底层采⽤分段的数组+链表实现,JDK1.8 时采⽤的数据结构跟HashMap1.8 的结构⼀样,数组+链表/红⿊⼆叉树。Hashtable和 JDK1.8 之前的 HashMap的底层数据结构类似都是采⽤ 数组+链表 的形式,数组是HashMap的主体,链表则是主要为了解决哈希冲突⽽存在的;
  • 实现线程安全的⽅式(重要):① 在 JDK1.7 的时候,ConcurrentHashMap(分段锁)对整个桶数组进⾏了分割分段(Segment),每⼀把锁只锁容器其中⼀部分数据,多线程访问容器⾥不同数据段的数据,就不会存在锁竞争,提⾼并发访问率。到了 JDK1.8 的时候已经摒弃了Segment的概念,⽽是直接⽤Node数组+链表+红⿊树的数据结构来实现,并发控制使⽤synchronizedCAS来操作。(JDK1.6 以后对synchronized锁做了很多优化)整个看起来就像是优化过且线程安全的HashMap,虽然在 JDK1.8 中还能看到Segment的数据结构,但是已经简化了属性,只是为了兼容旧版本;②Hashtable(同⼀把锁):使⽤synchronized来保证线程安全,效率⾮常低下。当⼀个线程访问同步⽅法时,其他线程也访问同步⽅法,可能会进⼊阻塞或轮询状态,如使⽤put添加元素,另⼀个线程不能使⽤put添加元素,也不能使⽤get,竞争会越来越激烈,效率很低。

两者的对⽐图:

HashTable:
file

JDK1.7 的 ConcurrentHashMap:

file

JDK1.8 的 ConcurrentHashMap:

JDK1.8 的 ConcurrentHashMap不在是Segment 数组 + HashEntry 数组 + 链表,⽽是Node 数组 + 链表/红⿊树。不过,Node只能⽤于链表的情况,红⿊树的情况需要使⽤TreeNode。当冲突链表达到⼀定⻓度时,链表会转换成红⿊树。

最后修改日期: 2021年11月25日

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。