后端学习笔记四 Map的几个实现类杂谈
Ruoyi-Vue 说到Map,不得不提的就是Java中的HashMap了,这个东西平时在写代码的时候是经常被使用的,这个东西的底层是由数组加上链表实现的,但是大家都知道的是HashMap是线程不安全的,因为多个线程对同一个HashMap做put操作的话,可能在某些情况下会有两个或者多个线程同时进行rehash操作,故而导致循环链表的出现,一旦出现就会死循环,cpu使用率会逐渐到达100%。 所以为了使用线程安全,又有了一个新的Map实现类:HashTable,说到多线程,肯定就会有锁的概念,为了实现HashTable的多线程同步,HashTable的底层实现了synchronized的锁结构,但是它效率比HashMap的效率要低一些,因为在多线程的情况下,HashTable会把整个结构全部锁住,为了解决遮盖1问题,在Jdk5中提出了ConcurrentHashMap这个新的数据结构。 这个ConcurrentHashMap提出的目的就是为了解决HashTable的低效率问题,使用了分段锁这个比较细粒度的锁,ConcurrentHashMap底层实现还是数组和链表,但是底层存储数据是一段一段的,每个段都有类似数组加上链表的结构,在进行get,put和remove操作时只锁住要用的段,但是以后每个段越来越大以后,分段锁的性能还是会下降的,但是在Jdk1.8以后,ConcurrentHashMap的底层实现变成了数组,链表/红黑树的形式。在链表中的元素个数超过默认的8个,数组的大小超过64后链表就变成红黑树了(想起这个树就脑壳痛),而且弃用分段锁,并且使用synchronized+CAS操作,目的就是为了降低锁的力度,因为synchronized是JVM支持的,在运行时会进行锁粗化,锁消除,锁自选等等操作。