`

HashMap与ConcurrentHashMap的区别

阅读更多

        从JDK1.2起,就有了HashMap,正如前一篇文章所说,HashMap不是线程安全的,因此多线程操作时需要格外小心。

        在JDK1.5中,伟大的Doug Lea给我们带来了concurrent包,从此Map也有安全的了。

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

        从ConcurrentHashMap代码中可以看出,它引入了一个“分段锁”的概念,具体可以理解为把一个大的Map拆分成N个小的HashTable,根据key.hashCode()来决定把key放到哪个HashTable中。

        在ConcurrentHashMap中,就是把Map分成了N个Segment,put和get的时候,都是现根据key.hashCode()算出放到哪个Segment中:

    /**
     * Maps the specified key to the specified value in this table.
     * Neither the key nor the value can be null.
     *
     * <p> The value can be retrieved by calling the <tt>get</tt> method
     * with a key that is equal to the original key.
     *
     * @param key key with which the specified value is to be associated
     * @param value value to be associated with the specified key
     * @return the previous value associated with <tt>key</tt>, or
     *         <tt>null</tt> if there was no mapping for <tt>key</tt>
     * @throws NullPointerException if the specified key or value is null
     */
    @SuppressWarnings("unchecked")
    public V put(K key, V value) {
        Segment<K,V> s;
        if (value == null)
            throw new NullPointerException();
        int hash = hash(key);
        int j = (hash >>> segmentShift) & segmentMask;
        if ((s = (Segment<K,V>)UNSAFE.getObject          // nonvolatile; recheck
             (segments, (j << SSHIFT) + SBASE)) == null) //  in ensureSegment
            s = ensureSegment(j);
        return s.put(key, hash, value, false);
    }
    /**
     * Returns the value to which the specified key is mapped,
     * or {@code null} if this map contains no mapping for the key.
     *
     * <p>More formally, if this map contains a mapping from a key
     * {@code k} to a value {@code v} such that {@code key.equals(k)},
     * then this method returns {@code v}; otherwise it returns
     * {@code null}.  (There can be at most one such mapping.)
     *
     * @throws NullPointerException if the specified key is null
     */
    public V get(Object key) {
        Segment<K,V> s; // manually integrate access methods to reduce overhead
        HashEntry<K,V>[] tab;
        int h = hash(key);
        long u = (((h >>> segmentShift) & segmentMask) << SSHIFT) + SBASE;
        if ((s = (Segment<K,V>)UNSAFE.getObjectVolatile(segments, u)) != null &&
            (tab = s.table) != null) {
            for (HashEntry<K,V> e = (HashEntry<K,V>) UNSAFE.getObjectVolatile
                     (tab, ((long)(((tab.length - 1) & h)) << TSHIFT) + TBASE);
                 e != null; e = e.next) {
                K k;
                if ((k = e.key) == key || (e.hash == h && key.equals(k)))
                    return e.value;
            }
        }
        return null;
    }

        如果key.hashCode()相同,表示它们将会放在同一个Segment上,如果是并发放入的话,可能会阻塞直到前面的put动作完成。

        Segment.put方法:


        Segment.remove方法:



参考文章:http://blog.csdn.net/xuefeng0707/article/details/40834595

  • 大小: 21.2 KB
  • 大小: 35.3 KB
  • 大小: 22.9 KB
分享到:
评论

相关推荐

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

    与HashMap不同的是,ConcurrentHashMap是线程安全的,它使用了锁分段的机制,每个段都独立加锁,避免了多线程之间的竞争,提高了并发效率。ConcurrentHashMap的实现是基于HashMap的,它将数据分为多个segment,每个...

    HashMap与ConcurrentHashMap面试要点.pdf

    Node数组的结构与HashMap中的数组类似,但ConcurrentHashMap对数组的每个节点Node进行了CAS操作来保证并发时节点的安全更新。 ConcurrentHashMap的节点Node在冲突比较小的情况下以链表形式存储,当冲突较大时,链表...

    从HashMap到ConcurrentHashMap源码详解

    在Java集合框架中,HashMap与ConcurrentHashMap是两种最常用的哈希表实现,它们在性能和并发级别上有着显著的区别。本文将对这两个类的源码进行详解,深入分析其关键属性、方法实现、扩容机制以及并发实现等核心知识...

    HashMap&ConcurrentHashMap.key

    HashMap& ConcurrentHashMap 深度解析

    史上最详细详解hashmap、concurrenthashmap

    总结来说,HashMap 和 ConcurrentHashMap 主要的区别在于线程安全性和数据结构优化。HashMap 适合单线程环境,追求高性能;而 ConcurrentHashMap 在多线程环境下,通过分段锁和无锁并发控制提供线程安全的存取,牺牲...

    java7-8中的 HashMap和ConcurrentHashMap全解析.pdf

    在Java 7和8中,HashMap和ConcurrentHashMap是两种重要的数据结构,分别用于非线程安全和线程安全的键值对存储。本篇文章将深入解析这两种数据结构的内部实现,帮助读者理解它们的工作原理。 HashMap是Java中最常用...

    java7-8中的 HashMap和ConcurrentHashMap全解析

    在Java编程语言中,`HashMap`和`ConcurrentHashMap`是两种非常重要的数据结构,它们都属于`java.util`包,用于存储键值对。本文将深入解析这两个类在Java 7和8版本中的实现原理、特点以及使用场景。 首先,`HashMap...

    Java中Hashtable类与HashMap类的区别详解

    - `HashMap`则会对`hashCode()`进行再计算,以减少哈希冲突,使用与运算来确定元素在数组中的位置。 5. **容量和负载因子**: - `Hashtable`的初始容量是11,容量增长方式是旧容量的两倍加1。 - `HashMap`的默认...

    Java容器HashMap与HashTable详解

    《Java容器HashMap与HashTable详解》 HashMap和HashTable是Java中两种重要的数据结构,它们都是用于存储键值对的数据容器,但两者在设计和使用上有显著的差异。 HashMap是Java集合框架的一部分,它继承自...

    Java中HashMap和TreeMap的区别深入理解

    此外,如果在多线程环境中使用,应考虑使用ConcurrentHashMap(线程安全的HashMap变体)或Collections.synchronizedMap()来同步HashMap,以避免并发问题。 在实际开发中,根据需求选择合适的Map实现至关重要。如果...

    HashMap 和 Hashtable的区别

    HashMap 和 Hashtable 是 Java 集合框架中两个重要的 Map 实现,它们虽然都是用来存储键值对的数据结构,但在很多方面存在显著的区别。以下将详细分析它们的主要差异、工作原理和适用场景。 1. **线程安全性** - `...

    HashMap底层实现原理HashMap与HashTable区别HashMap与HashSet区别.docx

    HashMap与HashTable的主要区别在于线程安全性和对null值的支持。HashMap是非同步的,意味着在多线程环境中,如果不进行适当的同步控制,可能会导致数据不一致。而HashTable是同步的,因此它在多线程环境下的安全性更...

    HashMap 和 HashSet的区别

    - 与之相比,虽然Java提供线程安全的HashMap替代品如`ConcurrentHashMap`,但HashSet没有线程安全的对应版本。 5. **排序**: - HashSet中的元素没有特定的顺序,插入的顺序可能不等于遍历的顺序。 - HashMap...

    HashMap与HashTable区别

    ### HashMap与HashTable的区别 在Java编程语言中,`HashMap`和`HashTable`是两种非常重要的数据结构,它们都实现了`Map`接口,并提供了键值对的存储方式。这两种数据结构虽然相似,但在实现细节和使用场景上存在...

    java无锁hashmap原理与实现详解

    Java无锁HashMap是一种在多线程环境下高效运行的...在Java中,`ConcurrentHashMap`是无锁HashMap的一种实现,它在高并发场景下提供了很好的性能表现。理解并掌握这些概念和技术,对于开发高效的并发应用程序至关重要。

    ConcurrentHashmap源码

    源码分析见我博文:http://blog.csdn.net/wabiaozia/article/details/50684556

    java面试题——详解HashMap和Hashtable 的区别

    HashMap 和 Hashtable 是 Java 中两种常用的哈希表数据结构,它们都是用来存储键值对的数据结构,但它们在设计和实现上有显著的区别。以下是对这两者差异的详细解释: 1. **线程安全性**: - `Hashtable` 是线程...

    浅析java中ArrayList与Vector的区别以及HashMap与Hashtable的区别

    - `HashMap` 不是线程安全的,如果需要在多线程环境中使用,需要手动进行同步控制,如使用synchronized关键字或者并发包下的ConcurrentHashMap。 3. **值的约束**: - `Hashtable` 不允许null作为键(key)或值...

    HASHMAP结构及版本区别.docx

    为了解决这个问题,Java提供了ConcurrentHashMap类,它是线程安全的HashMap实现,可以用于多线程环境。例如,可以使用`ConcurrentHashMap map = new ConcurrentHashMap(32);`来创建一个具有32个初始容量的线程安全的...

    Java并发系列之ConcurrentHashMap源码分析

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

Global site tag (gtag.js) - Google Analytics