首页 > 其他 > 详细

浅谈ConcurrentHashMap和HashTable

时间:2020-08-22 23:02:59      阅读:88      评论:0      收藏:0      [点我收藏+]

前言

我们知道HashMap是线程不安全的,那么当我们要在多线程的情况下,应该怎么办呢?

在多线程场景下,我们一般采用下面的几种方式去创建线程安全的map集合

  1. 采用Collections.synchronizedMap(Map)
  2. 采用Hashtable
  3. 采用ConcurrentHashMap

通常会采用ConcurrentHashMap,因为前面两者的并发度太低了。

Collections.synchronizedMap(Map)

synchronizedMap是Collections工具类中的一个内部类。
从下面的源码中可以看出来,SynchronizedMap维护了一个Map和一个互斥锁

    private static class SynchronizedMap<K,V>
        implements Map<K,V>, Serializable {
        private static final long serialVersionUID = 1978198479659022715L;

        // Map对象
        private final Map<K,V> m;     // Backing Map
        // 互斥锁
        final Object      mutex;        // Object on which to synchronize

        SynchronizedMap(Map<K,V> m) {
            this.m = Objects.requireNonNull(m);
            mutex = this;
        }

        SynchronizedMap(Map<K,V> m, Object mutex) {
            this.m = m;
            this.mutex = mutex;
        }
      .................
      ................
    }

可以看到有两个构造器,需要传入一个Map对象,如果没有传入互斥锁对象,那么互斥锁会赋值为this

创建好之后对map的各种操作都是带锁的,??

        public int size() {synchronized (mutex) {return m.size();}}
        public boolean isEmpty() {synchronized (mutex) {return m.isEmpty();}}
        public boolean containsKey(Object key) {synchronized (mutex) {return m.containsKey(key);}}
        public boolean containsValue(Object value) {synchronized (mutex) {return m.containsValue(value);}}
        public V get(Object key) {synchronized (mutex) {return m.get(key);}}

所以并发度很低,每次只允许一个线程对数据进行操作

Hashtable

Hashtable和HashMap的结构差不多。
Hashtable是线程安全的原因是因为,他在操作数据的方法上都加了synchronized,同样的,这也导致他的效率非常低。

    public synchronized int size() {
        return count;
    }
    public synchronized V get(Object key) {
        Entry<?,?> tab[] = table;
        int hash = key.hashCode();
      .......
      .......
    }

Hashtable和HashMap的区别

Hashtable HashMap
线程安全 线程不安全
继承Dictionary 继承AbstractMap
不允许key或者value为null 允许为null
数组默认大小为11,扩容为2*old+1 数组默认大小为16 , 扩容为2*old

其实现在多线程环境下一般也不用Hashtable,他是一个遗留类,内部实现很多没有优化

ConcurrentHashMap

一般开发中用的都是ConcurrentHashMap,并发度高,效率高。
同样的,ConcurrentHashMap的键值不允许为null
1.7的时候采用的是分段锁的方式。(给每个段(Segment)用lock锁进行保护,相对Hashtable的synchronized关键字锁粒度更细,并发度更高)
1.8的时候优化成CAS+synchronized的方式。
具体详见??
ConcurrentHashMap源码分析

浅谈ConcurrentHashMap和HashTable

原文:https://www.cnblogs.com/bendandedaima/p/13546856.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!