HashMap与ConcurrentHashMap的区别
1.基本概念不同
ConcurrentHashMap是一个支持高并发更新与查询的哈希表。在保证安全的前提下,进行检索不需要锁定。
HashMap是基于哈希表的Map接口的实现,此实现提供所有可选的映射操作,并允许使用null值和null键。
2.底层数据结构不同
HashMap的底层数据结构主要是:数组+链表,确切的说是由链表为元素的数组。
ConcurrentHashMap的底层数据结构是:Segments数组+HashEntry数组+链表。
3.线程安全属性不同
ConcurrentHashMap是线程安全的数组,它采用分段锁保证安全性。容器中有多把锁,每一把锁锁一段数据,这样在多线程访问时不同段的数据时,就不会存在锁竞争了,这样便可以有效地提高并发效率。
而HashMap不是线程安全,没有锁机制,在多线程环境下会导致数据覆盖之类的问题,所以在多线程中使用HashMap是会抛出异常的。
4.对整个桶数组的处理方式不同
ConcurrentHashMap对整个桶数组进行了分段;而HashMap则没有对整个桶数组进行分段。
实例:
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
public class HashMapDemo {
public static void main(String[] args) throws InterruptedException {
Map<Integer, Integer> map = new HashMap<>();
//Map<Integer, Integer> map = new ConcurrentHashMap<>();
CountDownLatch countDownLatch = new CountDownLatch(4);
new Thread(() -> {
for (int i = 0; i < 1000; i++) {
map.put(i, i);
}
countDownLatch.countDown();
}).start();
new Thread(() -> {
for (int i = 1000; i < 2000; i++) {
map.put(i, i);
}
countDownLatch.countDown();
}).start();
new Thread(() -> {
for (int i = 2000; i < 3000; i++) {
map.put(i, i);
}
countDownLatch.countDown();
}).start();
new Thread(() -> {
for (int i = 3000; i < 4000; i++) {
map.put(i, i);
}
countDownLatch.countDown();
}).start();
countDownLatch.await();
System.out.println(map.size());
}
}
我们开启四个线程向HashMap中添加4000个键值对,其结果为:
3884
说明HashMap的put方法并不能保证线程安全。替换为ConcurrentHashMap,其结果为:
4000
ConcurrentHashMap是线程安全的Map,它采用分段锁保证了线程安全性。