这里呢,在我们学习多线程之前,HashMap,在数据结构中我们都已经非常熟悉了,HashMap,有key和value,key和value都是一一对应的关系。key允许为null。
而当我们学习过线程之后呢,HashMap是线程不安全的。
而HashTable是线程安全的,在创建的时候,他会给 this加锁,使线程安全,但是这样的加锁,在我们多个线程对数据进行读写操作的时候,会发生阻塞,效率非常低,他的key不能为null。
在这里我们又引入了ConcurrentHashMap ,他是线程安全 ,使⽤synchronized锁每个链表头结点,锁冲突概率低,充分利⽤ CAS机制,优化了扩容⽅式,key不允许为null。
ConcurrentHashMap的优化
相比于Hashtable做出了⼀系列的改进和优化.
以Java1.8为例
• 读操作没有加锁(但是使用了volatile保证从内存读取结果),只对写操作进行加锁。加锁的方式仍然 是是⽤synchronized,但是不是锁整个对象,而是"锁桶"(用每个链表的头结点作为锁对象),大大降 低了锁冲突的概率。
• 充分利用CAS特性,比如size属性通过CAS来更新,避免出现重量级锁的情况。
• 优化了扩容方式:化整为零。
◦发现需要扩容的线程,只需要创建一个新的数组,同时只搬几个元素过去。
◦ 扩容期间,新老数组同时存在。
◦ 后续每个来操作ConcurrentHashMap的线程,都会参与搬家的过程,每个操作负责搬运⼀小部 分元素。
◦ 搬完最后⼀个元素再把老数组删掉。
◦ 这个期间,插入只往新数组加。
◦ 这个期间,查找需要同时查新数组和老数组。