← 返回首页
HashMap与ConcurrentHashMap的区别
发表时间:2023-04-06 16:48:21
HashMap与ConcurrentHashMap的区别

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,它采用分段锁保证了线程安全性。