HashTable 和 ConcurrentHashMap 的区别
HashMap:不是线程安全的,不能应用于多线程的场景下。
HashTable:是一个线程安全的类,使用synchronized来锁住整张Hash表来实现线程安全,坏处就是锁冲突概率非常高。
HashTable的扩容当某个线程正好触发扩容,这个线程就要负责完成整个扩容过程。
ConcurrentHashMap:
- 并不是针对整个对象加一把锁,而是分成了很多把锁。每个链表/红黑树分配一把锁,只有当两个线程恰好修改的是同一个链表/红黑树的时候才会涉及到锁冲突。
- 针对读操作不加锁。读操作不一定能够读到最新的数据。
- 内部广泛使用了CAS操作来提高效率。例如获取元素个数时没加锁直接CAS;修改元素获取对应链表的下标时用CAS。
- 针对扩容进行优化。将扩容任务分开,一次扩容一部分,支持多个线程同时进行扩容,并没有加锁。
其他区别:HashMap允许key值为null;HashTable和ConcurrentHashMap不允许key为null。