zoukankan      html  css  js  c++  java
  • HashMap与ConcurrentHashMap的区别

    转自:http://blog.csdn.net/xuefeng0707/article/details/40834595 

    从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中:






    测试程序:

    1. import java.util.concurrent.ConcurrentHashMap;  
    2.   
    3. public class ConcurrentHashMapTest {  
    4.       
    5.     private static ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<Integer, Integer>();  
    6.     public static void main(String[] args) {  
    7.         new Thread("Thread1"){  
    8.             @Override  
    9.             public void run() {  
    10.                 map.put(3, 33);  
    11.             }  
    12.         };  
    13.           
    14.         new Thread("Thread2"){  
    15.             @Override  
    16.             public void run() {  
    17.                 map.put(4, 44);  
    18.             }  
    19.         };  
    20.           
    21.         new Thread("Thread3"){  
    22.             @Override  
    23.             public void run() {  
    24.                 map.put(7, 77);  
    25.             }  
    26.         };  
    27.         System.out.println(map);  
    28.     }  
    29. }  


    ConcurrentHashMap中默认是把segments初始化为长度为16的数组。

    根据ConcurrentHashMap.segmentFor的算法,3、4对应的Segment都是segments[1],7对应的Segment是segments[12]。

    (1)Thread1和Thread2先后进入Segment.put方法时,Thread1会首先获取到锁,可以进入,而Thread2则会阻塞在锁上:


    (2)切换到Thread3,也走到Segment.put方法,因为7所存储的Segment和3、4不同,因此,不会阻塞在lock():



    以上就是ConcurrentHashMap的工作机制,通过把整个Map分为N个Segment(类似HashTable),可以提供相同的线程安全,但是效率提升N倍,默认提升16倍。

  • 相关阅读:
    Minimum Depth of Binary Tree leetcode java
    Maximum Depth of Binary Tree leetcode java
    Symmetric Tree leetcode java
    Same Tree leetcode java
    Binary Tree Postorder Traversal leetcode java
    Binary Tree Preorder Traversal leetcode java
    Binary Tree Inorder Traversal leetcode java
    Combinations leetcode java
    一键清除Centos iptables 防火墙所有规则
    阿里云centos7.7x64安装open,并配置ip转发和nat伪装
  • 原文地址:https://www.cnblogs.com/xifenglou/p/6554513.html
Copyright © 2011-2022 走看看