HashMap不是线程安全的,HashTable虽然是线程安全,但是该类所有的方法都用synchronized进行线程安全的控制,在高并发的情况下,同一时刻只有一个线程可以获取对象监视器,其他线程阻塞或者轮询等待,在线程竞争激烈的情况下,这种方式的效率会非常的低下。
HashTable在扩容的时候,newSize = 2 * oldSize + 1;
ConcurrentHashMap是线程安全的,使用了锁分段的思想提高了并发度。
ConcurrentHashMap为什么高效:
Hashtable低效主要是因为所有访问Hashtable的线程都争夺一把锁。如果容器有很多把锁,每一把锁控制容器中的一部分数据,那么当多个线程访问容器里的不同部分的数据时,线程之前就不会存在锁的竞争,这样就可以有效的提高并发的访问效率。这也正是ConcurrentHashMap使用的分段锁技术。将ConcurrentHashMap容器的数据分段存储,每一段数据分配一个Segment(锁),当线程占用其中一个Segment时,其他线程可正常访问其他段数据。
jdk1.7下ConcurrentHashMap的数据结构:
ConcurrentHashMap包含一个Segment数组,每个Segment包含一个HashEntry数组,当修改HashEntry数组采用开链法处理冲突,所以它的每个HashEntry元素又是链表结构的元素。
查找元素时,先通过key定位到Segment