HashMap、Hashtable、ConcurrentHashMap三者的区别

HashMap线程不安全,数组+链表+红黑树
HashMap线程不安全的原因:
因为多线程环境下,使用Hashmap进行put操作可能会引起死循环,导致CPU利用率接近100%,所以在并发情况下不能使用HashMap
Hashtable线程安全,锁住整个对象,数组+链表
Hashtable容器使用synchronized来保证线程安全,但在线程竞争激烈的情况下Hashtable的效率非常低下
ConcurrentHashMap线程安全,CAS+同步锁(synchronized),数组+链表+红黑树
HashMap的key,value均可为null,其他两个不行。
 
ConcurrentHashMap避免了对全局加锁改成了局部加锁操作,这样就极大地提高了并发环境下的操作速度,由于ConcurrentHashMap在JDK1.7和1.8中的实现非常不同:
在JDK1.7中ConcurrentHashMap采用了数组+Segment+分段锁的方式实现。
JDK8中ConcurrentHashMap参考了JDK8 HashMap的实现,采用了数组+链表+红黑树的实现方式来设计,内部大量采用CAS操作,这里我简要介绍下CAS。
CAS是compare and swap的缩写,即我们所说的比较交换。cas是一种基于锁的操作,而且是乐观锁。

CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。如果内存地址里面的值和A的值是一样的,那么就将内存里面的值更新成B。CAS是通过无限循环来获取数据的,若果在第一轮循环中,a线程获取地址里面的值被b线程修改了,那么a线程需要自旋,到下次循环才有可能机会执行。

JDK8中彻底放弃了Segment转而采用的是Node,其设计思想也不再是JDK1.7中的分段锁思想。

Node:保存key,value及key的hash值的数据结构。其中value和next都用volatile修饰,保证并发的可见性。




posted @ 2020-03-17 10:17  再见傅里叶  阅读(273)  评论(0编辑  收藏  举报