目录
一、多线程环境使用哈希表
1.1 HashTable
1.2 ConcurrentHashTable
二、ConcurrentHashMap和Hashtable、HashMap 的区别
一、多线程环境使用哈希表
HashMap 本身就是线程不安全的,所以在多线程的环境下可以使用:HashTable、 ConcurrentHashMap
1.1 HashTable
HashTable 只是简单的把关键方法加上了 synchronized 关键字
这就相当于对 HashTable 本身直接加锁
- 如果多线程直接访问同一个HashTable 就会直接造成冲突
- size属性也是通过synchronized来控制同步,也会降低效率
- 一旦触发扩容,该线程就会完成整个扩容的效果,这个过程会涉及到大量的元素拷贝,效率很低
1.2 ConcurrentHashTable
ConcurrentHashTable 没有直接对整个方法进行加锁,而是进行 “锁桶” 操作,这样就会大大降低锁冲突的概率。
- 读操作没有加锁(但是使用了 volatile 关键字保证从内存中读取结果)
- 利用CAS的特性来控制size 属性,避免出现重量级锁的情况。
- 优化了扩容方式:化整为零
- 发现需要扩容的线程, 只需要创建一个新的数组, 同时只搬几个元素过去.
- 扩容期间, 新老数组同时存在.
- 后续每个来操作 ConcurrentHashMap 的线程, 都会参与搬家的过程. 每个操作负责搬运一小部分元素.
- 搬完最后一个元素再把老数组删掉.
- 这个期间, 插入只往新数组加.
- 这个期间, 查找需要同时查新数组和老数组
二、ConcurrentHashMap和Hashtable、HashMap 的区别
- HashMap: 线程不安全。key 允许为 null
- Hashtable: 线程安全。使用 synchronized 锁 Hashtable 对象,效率较低。key 不允许为 null。
- ConcurrentHashMap: 线程安全。使用 synchronized 锁每个链表头结点,锁冲突概率低,充分利用了CAS 机制。同时优化了扩容方式。key 不允许为 null。