目录
- 前言
- 1.HashTable
- 2.ConcurrentHashMap
- 总结
前言
在使用多线程前,我们用HashMap类来创建哈希表,但这个类线程不安全,在这篇文章,我们将介绍多线程环境的哈希表,将会讲述HashTable, HashMap, ConcurrentHashMap这三个类的主要区别。
1.HashTable
HashTable实际上就是线程安全的HashMap,两者的功能十分相似,只是HashTable会在代码一些关键地方进行加锁,比如看其中的get方法:
HashTable虽然是线程安全的类,但已经不推荐使用了,我们目前主流使用的就是接下来要提到的ConcurrentHashMap。
2.ConcurrentHashMap
ConcurrentHashMap是针对多线程场景专门优化的一个哈希表,使用方法和普通的哈希表一样。
ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<>();
ConcurrentHashMap,对比于HashTable,最大的调整是针对锁的粒度进行了优化,上面可以看到,HashTale针对this进行加锁,如果进行操作,针对任何一个进程,都会对整个哈希表触发锁竞争。
而ConcurrentHashMap上,对哈希表上的每一个链表都提供了一个锁。也就是说,在针对哈希表中同一个链表的修改才会引入阻塞。这样的方案使竞争更小。
此外ConcurrentHashMap采取了原子类的放哪,基于CAS操作来针对size进行变更。
在ConcurrentHashMap扩容的时候,不会把所有键值对都搬运到更大的数组上,每次只运一部分,来确保单次搬运的速度足够快,使锁的持有时间足够短,减少开销。具体是每次进行get,put,remove等操作时,都会搬运一部分。
总结
本篇文章讲述了HashTable, HashMap, ConcurrentHashMap的主要区别,其中ConcurrentHashMap的区别最多,优化最好,需要着重进行理解。