视频课程
小黑屋思过中,禁止观看!
评论并刷新后可见

您需要在视频最下面评论并刷新后,方可查看完整视频

视频课程
立即观看
付费视频

您支付费用,方可查看完整视频

¥{{user.role.value}}
课程视频
开始学习
会员专享

视频合集

ConcurrentHashMap的实现原理,源码深度剖析!

  • 课程笔记
  • 问答交流

HashMapArrayList、Vector、LinkedListCopyOnWriteList这些都属于重点掌握内容了,除此以外还有一个非常重要的ConcurrentHashMap。

为了助大家掌握好ConcurrentHashMap,这节课我会重点讲解以下4点:

1.Hashtable源码剖析

2.Collections.SynchronizedMap源码剖析

3.ConcurrentHashMap JDK1.7源码剖析

4.ConcurrentHashMap JDK1.8源码剖析

Hashtable

ConcurrentHashMap的实现原理,源码深度剖析!-mikechen
Hashtable 中几个比较重要的方法

public synchronized V put(K key, V value) {...}
public synchronized V get(Object key) {...}
public synchronized int size() {...}
public synchronized boolean remove(Object key, Object value) {...}
public synchronized boolean contains(Object value) {...}

直接在方法声明上使用 synchronized 关键字,Hashtable 实现线程安全的原理相当简单粗暴。

Collections.SynchronizedMap

SynchronizedMap 是 Collections 集合类的私有静态内部类,其定义和构造方法如下:

private static class SynchronizedMap<K,V> implements Map<K,V>, Serializable {
        private static final long serialVersionUID = 1978198479659022715L;
          // 用于接收传入的Map对象,也是类方法操作的对象
        private final Map<K,V> m;     
          // 锁对象
        final Object mutex;   
  
         // 以下是SynchronizedMap的两个构造方法
        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;
        }


}


//常用的方法


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 V get(Object key) {
    synchronized (mutex) {return m.get(key);}
}
public V put(K key, V value) {
    synchronized (mutex) {return m.put(key, value);}
}
public V remove(Object key) {
    synchronized (mutex) {return m.remove(key);}
}

ConcurrentHashMap JDK1.7

评论交流
  1. 路正银

    hashMap是线程不安全的,hashMap的线程安全替代方案有以下四个:
    1、hashtable 对所有方法加锁(synchronized),所有线程锁的都是当前对象,锁的粒度太大
    2、Collections.SynchronizedMap 锁的是同一个对象,每次锁的都是当前整张表,锁的粒度太大
    3、ConcurrentHashMap JDK1.7 分段锁,通过hash计算,在找桶的位置之前,先去找锁的位置(对桶中位置分组的概念),缺点之一,每次确定位置,需要两次hash计算
    4、ConcurrentHashMap JDK1.8 锁的粒度很小,当发生hash冲突的时候会去加锁,锁的是当前链表的头结点
    实现方式:Node数组+CAS(桶中的头结点为空,用cas的方式做插入操作)+Synchronized(hash冲突,往后挂链表的时候加锁)+Volatile(多线程环境之下的可见性)

    ConcurrentHashMap JDK1.8 put方法流程图如下:

    • mikechen

      言简意赅,直切重点 ✗棒棒的✗

      这里我再补充下另外两点:

      1.ConcurrentHashMap 这个版本之所以高,还有一个非常核心的原因就是:ConcurrentHashMap 的查询get方法是没有加锁的,读是没有锁,写的时候才会涉及到锁。

      2.比如hashtable 、Collections.SynchronizedMap无论是读还是写都会加锁,ConcurrentHashMap读上是没有锁的(依赖于Volatile的可见性来解决),再加上ConcurrentHashMap 1.8版本又把锁的粒度降低了,所以在并发的情况下性能较高。