`
TranCoffee
  • 浏览: 9484 次
社区版块
存档分类
最新评论

ConcurrentHashMap实现分析

阅读更多
java5中新增了ConcurrentMap接口和它的一个实现类ConcurrentHashMap.该类在多线程并发情况下的效率要比HashTable和Collections.synchronizedMap()返回的map效率要高。原因是它的锁实现的很“机智”。
HashTable和Collections的内部类SynchronizedMap里的同步,都是用synchronized来实现的,每次都是锁整个表,因此同一时刻只能有一个线程操作hash表。
而ConcurrentHashMap中使用了Segment[]来存储数据,Segment继承自ReentrantLock类(这样执行lock操作就方便了),默认情况下有16个Segment,当put数据时,会看这个key的hash值对应到哪个Segment里面,然后只锁这个Segement,所以它允许多个线程同时put。(读操作一般不需要加锁,除非发生特殊情况)
Segemnt
/**
     * The segments, each of which is a specialized hash table
     */
    final Segment<K,V>[] segments;
 
/**
     * Segments are specialized versions of hash tables.  This
     * subclasses from ReentrantLock opportunistically, just to
     * simplify some locking and avoid separate construction.
     */
    static final class Segment<K,V> extends ReentrantLock implements Serializable {



ConcurrentHashMap的put()方法:
public V put(K key, V value) {
        if (value == null)
            throw new NullPointerException();
        int hash = hash(key.hashCode());
        return segmentFor(hash).put(key, hash, value, false);
    }

  /**
     * Returns the segment that should be used for key with given hash
     * @param hash the hash code for the key
     * @return the segment
     */
    final Segment<K,V> segmentFor(int hash) {
        return segments[(hash >>> segmentShift) & segmentMask];
    }

先根据key的hash值计算所属的Segment,然后执行该Segment的put()方法。

Segemnt的put()方法:
 V put(K key, int hash, V value, boolean onlyIfAbsent) {
            lock();
            try {
                int c = count;
                if (c++ > threshold) // ensure capacity
                    rehash();
                HashEntry<K,V>[] tab = table;
                int index = hash & (tab.length - 1);
                HashEntry<K,V> first = tab[index];
                HashEntry<K,V> e = first;
                while (e != null && (e.hash != hash || !key.equals(e.key)))
                    e = e.next;

                V oldValue;
                if (e != null) {
                    oldValue = e.value;
                    if (!onlyIfAbsent)
                        e.value = value;
                }
                else {
                    oldValue = null;
                    ++modCount;
                    tab[index] = new HashEntry<K,V>(key, hash, first, value);
                    count = c; // write-volatile
                }
                return oldValue;
            } finally {
                unlock();
            }
        }

由于Segment继承自ReentrantLock,因此可以很方便的调用lock()和unlock().

综述,由于ConcurrentHashMap采用了分段锁(或者说锁分离),并且对存储size等操作做了一些加锁优化,因此其效率要高一些。重点还是分段锁。

有一篇介绍ConcurrentHashMap的文章,分享一下:
http://www.iteye.com/topic/344876

分享到:
评论

相关推荐

    ConcurrentHashMap源码分析

    ConcurrentHashMap具体是怎么实现线程安全的呢,肯定不可能是每个方法加synchronized,那样就变成了HashTable。

    ConcurrentHashMap底层实现机制的分析1

    ConcurrentHashMap底层实现机制的分析1

    程序员面试加薪必备:ConcurrentHashMap底层原理与源码分析深入详解

    程序员面试加薪必备_ConcurrentHashMap底层原理与源码分析深入详解

    ConcurrentHashMap思维导图完整版

    本文将结合Java内存模型,分析JDK源代码,探索ConcurrentHashMap高并发的具体实现机制,包括其在JDK中的定义和结构、并发存取、重哈希和跨段操作,并着重剖析了ConcurrentHashMap读操作不需要加锁和分段锁机制的内在...

    JDK1.8 ConcurrentHashMap的一点理解

    只是都是相通的,当我们了解了ConcurrentHashMap的实现原理以及各个方法的实现机制,我们对于其他的hash类型实现也能快速的理解,今天我们就来通过源码来一点一点的分析下ConcurrentHashMap的实现。 首先我们来看...

    Java理论与实践:构建一个更好的HashMap

    本文分析Doug Lea的util.concurrent包中的ConcurrentHashMap的实现。并针对吞吐量进行优化,对于大多数一般用法来说它是经过优化的,这些用法往往会检索一个很可能在map中已经存在的值。ConcurrentHashMap摒弃了单一...

    ConcurrentHashmaq源码分析.txt

    ConcurrentHashMap理论概述,实现原理,简单的源码分析,put和get的简单学习

    聊聊并发系列文章

    4. 聊聊并发(四)深入分析ConcurrentHashMap 5. 聊聊并发(五)原子操作的实现原理 6. 聊聊并发(六)ConcurrentLinkedQueue的实现原理 7. 聊聊并发(七)Java中的阻塞队列 8. 聊聊并发(八)Fork/Join框架介绍 9. ...

    Java并发容器,底层原理深入分析

    ConcurrentHashMapConcurrentHashMap底层具体实现JDK1.7底层实现将数据分为一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据时,其他段的数据也能被其他线程访问。ConcurrentHashMap...

    Java并发包源码分析(JDK1.8)

    AQS相关应用(CountDownLatch、CyclicBarrier、Semaphore等),executor(ThreadPoolExecutor、ScheduledThreadPoolExecutor、FutureTask等),collection(ConcurrentHashMap、CopyOnWriteArrayList等), ...

    Java多线程和并发知识整理

    3.2 原理分析 3.3 JVM中锁的优化 3.4 Synchronized与Lock 3.5 扩展 四、volatile 详解 4.1 作用 4.2 实现原理 4.3 应用场景 五、final 详解 5.1 基础 5.2 重排序规则 5.3 扩展 六、JUC 6.1 汇总 6.2 ...

    java8集合源码分析-Outline:大纲

    集合源码分析 JAVA: 基本语法 static 修饰变量 方法 静态块(初始化块 构造函数 ) 静态内部类() 静态导包 final() transient() foreach循环原理() volatile底层实现() equals和hashcode(, ) string,stringbuffer和...

    Java面试题-并发.docx

    特别强调了Hashtable不允许插入null的原因,以及ConcurrentHashMap在线程安全实现和锁优化方面的策略。 总的来说,这份文档对HashMap的各个方面进行了全面而详细的阐述,既适合作为面试准备的参考资料,也适用于...

    Java面试题-哈希.docx

    特别强调了Hashtable不允许插入null的原因,以及ConcurrentHashMap在线程安全实现和锁优化方面的策略。 总的来说,这份文件对HashMap的各个方面进行了全面而详细的阐述,既适合作为面试准备的参考资料,也适用于...

    汪文君高并发编程实战视频资源全集

     高并发编程第三阶段11讲 AtomicXXXFieldUpdater源码分析及使用场景分析.mp4  高并发编程第三阶段12讲 sun.misc.Unsafe介绍以及几种Counter方案性能对比.mp4  高并发编程第三阶段13讲 一个JNI程序的编写,通过...

    汪文君高并发编程实战视频资源下载.txt

     高并发编程第三阶段11讲 AtomicXXXFieldUpdater源码分析及使用场景分析.mp4  高并发编程第三阶段12讲 sun.misc.Unsafe介绍以及几种Counter方案性能对比.mp4  高并发编程第三阶段13讲 一个JNI程序的编写,通过...

    algorithm-study:你好,世界

    :green_apple: :red_apple: :pear: :melon: :avocado: :potato: ...java动态代理实现与原理详细分析 描述动态代理的几种实现方式,分别说出相应的优缺点。 动态代理与cglib实现的区别。 为什么CGlib

    Java-Interview:此项目为 Java 面试的汇总,多数是一些 Java 基础知识、底层原理、算法详解。也有上层应用设计,其中不乏一些大厂面试真题

    ConcurrentHashMap 的实现原理 线程池原理 深入理解线程通信 交替打印奇偶数 JVM Java 运行时内存划分 类加载机制 OOM 分析 垃圾回收 对象的创建与内存分配 你应该知道的 volatile 关键字 分布式相关 分布式限流 ...

    java-interview

    ConcurrentHashMap 的实现原理 线程池原理 深入理解线程通信 交替打印奇偶数 JVM Java 运行时内存划分 类加载机制 OOM 分析 垃圾回收 对象的创建与内存分配 你应该知道的 volatile 关键字 分布式相关 分布式限流 ...

Global site tag (gtag.js) - Google Analytics