由于HashMap本身并不是线程安全的,在多线程环境下,使用哈希表时我们通常使用Hashtable和ConcurrentHashMap。
1.HashTable
Hashtable只是简单粗暴给每个方法加上了synchronized关键字,就相当于是针对this加锁,不过这样加锁会带来问题(并不推荐使用):
1) 如果多线程访问同一个Hashtable就会造成锁冲突
2) size属性也是通过synchronized来控制同步,效率比较低
3) 当触发扩容时,会由此线程完成整个扩容过程,涉及到大量的元素拷贝,效率非常低
2.ConcurrentHashMap
针对上述问题,ConcurrentHashMap做出了一定的优化
1) 使用“锁桶”的方式,来代替“一把全局锁”,有效地降低了锁冲突的概率
2) 引入CAS,使用CAS的方式来修改size,避免了加锁操作
3) 针对扩容操作做了特殊优化(ConcurrentHashMap在扩容时,会有两份空间,一份扩容之前的空间,一份扩容之后的空间,每次进行哈希表的基本操作时,都会把一部分数据从旧空间搬运到新空间)