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

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底层实现机制的分析1

    ConcurrentHashMap 底层实现机制分析 在本文中,我们将深入探索 ConcurrentHashMap 的高并发实现机制,并分析其在 Java 内存模型基础上的实现原理。了解 ConcurrentHashMap 的实现机制有助于我们更好地理解 Java ...

    Java并发系列之ConcurrentHashMap源码分析

    Java并发系列之ConcurrentHashMap源码分析 ConcurrentHashMap是Java中一个高性能的哈希表实现,它解决了HashTable的同步问题,允许多线程同时操作哈希表,从而提高性能。 1. ConcurrentHashMap的成员变量: ...

    Java中的几个HashMapConcurrentHash

    `Java中的几个HashMap ConcurrentHashMap实现分析Java开发Java经验技巧共4页.pdf.zip`这个压缩包文件很可能包含了一些深入的分析和实践案例,可以帮助你更好地理解和运用这些数据结构。在实践中不断探索和总结,是...

    ConcurrentHashMap之实现细节

    ### ConcurrentHashMap实现细节详解 #### 一、概述 `ConcurrentHashMap`是Java 5引入的一种高性能、线程安全的散列表实现。相较于传统的`HashMap`,`ConcurrentHashMap`能够支持高并发环境下的多线程读写操作。...

    第二章 ConcurrentHashMap源码分析(JDK8版本)1

    在JDK8中,`ConcurrentHashMap`的实现方式与之前的版本(如JDK6)有了显著变化,去除了Segment锁段的概念,转而采用了一种基于CAS(Compare And Swap)算法的新机制,以提高并发性和效率。 1. **重要的属性** - `...

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

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

    ConcurrentHashMap源码解析

    通过以上分析,我们可以看到ConcurrentHashMap如何通过锁分段技术来解决HashMap在并发环境下的线程安全问题,并通过巧妙的设计减少线程间锁的竞争,从而提升性能。因此,在设计需要高并发性能的程序时,...

    ConcurrentHashMap思维导图完整版

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

    JDK1.8中ConcurrentHashMap中computeIfAbsent死循环bug.docx

    在并发环境下,`ConcurrentHashMap`通过分段锁(Segment)机制实现高效并发。每个Segment都是一个独立的`HashEntry`链表,每个链表节点包含键值对以及指向下一个节点的引用。在进行扩容时,`ConcurrentHashMap`会将...

    高薪程序员面试题精讲系列49之说说ConcurrentHashMap#put方法的源码及数。。。.pdf,这是一份不错的文件

    ConcurrentHashMap#put方法源码解析 ...通过对put方法的实现细节的分析,我们可以更好地理解ConcurrentHashMap的数据添加流程,从而更好地应用ConcurrentHashMap解决高并发情况下的数据存储问题。

    ConcurrentHashMap共18页.pdf.zip

    综上所述,"ConcurrentHashMap共18页.pdf.zip"这份文档很可能是深入分析 ConcurrentHashMap 的详细指南,涵盖了其设计原理、实现机制以及最佳实践。如果你对并发编程或者Java集合框架有深入需求,这份资料将是一份...

    concurrenthashmap1.7.docx

    本文主要分析`ConcurrentHashMap 1.7`的`put`方法及其涉及到的关键技术。 首先,`put`方法的执行流程要求`key`不能为`null`,否则会抛出`NullPointerException`。根据`key`的哈希值计算出`segments`数组的对应下标`...

    Java源码解析ConcurrentHashMap的初始化

    今天,我们将深入探讨ConcurrentHashMap的初始化过程,并分析其多线程间的同步机制。 首先,看一下ConcurrentHashMap的初始化代码: ```java private final Node,V&gt;[] initTable() { Node,V&gt;[] tab; int sc; ...

    JDK1.8 ConcurrentHashMap的一点理解

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

    java ConcurrentHashMap锁分段技术及原理详解

    在`ConcurrentHashMap`的源码分析中,可以看到它通过`volatile`关键字保证了`HashEntry`中`value`字段的可见性,确保了读操作的正确性,而其他字段如`key`、`hash`和`next`都是`final`的,防止在链表中进行中间插入...

    聊聊并发(4)深入分析ConcurrentHashMapJ

    本文将深入分析`ConcurrentHashMap`的设计原理、性能特点以及常见使用场景,帮助你提升Java并发编程的技能。 `ConcurrentHashMap`是`java.util.concurrent`包下的一个类,它在`HashMap`的基础上进行了优化,以适应...

    详谈HashMap和ConcurrentHashMap的区别(HashMap的底层源码)

    HashMap和ConcurrentHashMap是Java语言中两个常用的哈希表实现,它们都继承自AbstractMap类,实现了Map接口,但是它们之间存在着一些关键的区别。 首先,从数据结构上讲,HashMap是一个数组加链表的结构,根据key...

Global site tag (gtag.js) - Google Analytics