从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. public class ConcurrentHashMapTest {
  3. private static ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<Integer, Integer>();
  4. public static void main(String[] args) {
  5. new Thread("Thread1"){
  6. @Override
  7. public void run() {
  8. map.put(3, 33);
  9. }
  10. };
  11. new Thread("Thread2"){
  12. @Override
  13. public void run() {
  14. map.put(4, 44);
  15. }
  16. };
  17. new Thread("Thread3"){
  18. @Override
  19. public void run() {
  20. map.put(7, 77);
  21. }
  22. };
  23. System.out.println(map);
  24. }
  25. }

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倍。

HashMap与ConcurrentHashMap的区别(转)的更多相关文章

  1. 一、基础篇--1.2Java集合-HashMap和ConcurrentHashMap的区别【转】

    http://www.importnew.com/28263.html 今天发一篇”水文”,可能很多读者都会表示不理解,不过我想把它作为并发序列文章中不可缺少的一块来介绍.本来以为花不了多少时间的,不 ...

  2. HashMap与ConcurrentHashMap的区别

    从JDK1.2起,就有了HashMap,正如前一篇文章所说,HashMap不是线程安全的,因此多线程操作时需要格外小心. 在JDK1.5中,伟大的Doug Lea给我们带来了concurrent包,从 ...

  3. java基础知识再学习--HashMap与ConcurrentHashMap的区别

    引用:http://blog.csdn.net/xuefeng0707/article/details/40834595 从JDK1.2起,就有了HashMap,正如前一篇文章所说,HashMap不是 ...

  4. HashTable、HashMap、ConcurrentHashMap的区别

    HashTable是做了同步的,HashMap未考虑同步.所以HashMap在单线程情况下效率较高:HashTable在的多线程情况下,同步操作能保证程序执行的正确性. HashMap是非线程安全的, ...

  5. HashMap,HashTable,concurrentHashMap,LinkedHashMap 区别

    HashMap 不是线程安全的 HashTable,concurrentHashMap 是线程安全 HashTable 底层是所有方法都加有锁(synchronized) 所以操作起来效率会低 con ...

  6. HashMap与ConcurrentHashMap的区别<转>

    从JDK1.2起,就有了HashMap,正如前一篇文章所说,HashMap不是线程安全的,因此多线程操作时需要格外小心. 在JDK1.5中,伟大的Doug Lea给我们带来了concurrent包,从 ...

  7. HashMap与ConcurrentHashMap的区别(转)

    从JDK1.2起,就有了HashMap,正如前一篇文章所说,HashMap不是线程安全的,因此多线程操作时需要格外小心. 在JDK1.5中,伟大的Doug Lea给我们带来了concurrent包,从 ...

  8. 面试题:HashMap和ConcurrentHashMap的区别,HashMap的底层源码。

    Hashmap本质是数组加链表.根据key取得hash值,然后计算出数组下标,如果多个key对应到同一个下标,就用链表串起来,新插入的在前面. ConcurrentHashMap:在hashMap的基 ...

  9. HashMap和ConcurrentHashMap的区别,HashMap的底层源码。

    Hashmap本质是数组加链表.根据key取得hash值,然后计算出数组下标,如果多个key对应到同一个下标,就用链表串起来,新插入的在前面. ConcurrentHashMap:在hashMap的基 ...

随机推荐

  1. vi编辑器:命令模式、输入模式、末行模式

    1.命令模式(command mode)—执行命令 在该模式中,可以输入命令来执行许多种功能.控制屏幕光标的移动,字符.字或行的删除,移动复制某区段及进入Insert mode下,或者到 last l ...

  2. 编写自己的validate校验框架原理(转)

    原文链接:http://blog.csdn.net/a973893384/article/details/51517388 具体思路: 我们使用自定义注解实现.然后需要解决的是两个问题: 1是如何扫描 ...

  3. React typescript issue

    多个输入框发生变化时,setState: this.setState({[e.target.name]: e.target.value} as componentState)

  4. Flask 上下文管理-- (session,request,current_app的传递)--类似本地线程实现,以及多app应用

    Flask session,request,current_app的传递 请求上下文的作用 -- 封装请求相关得数据(request,session) 请求上下文 request session re ...

  5. R语言-数据类型与运算符

    一.在线安装包 install.packages(package_name) 二.查看变量 ls() 三.删除变量 rm() 四.变量类型 元数据类型:字符,整形,数字,虚数,BOOL 向量:vec= ...

  6. 关于json解析和所需jar

    以解析字符串数组为例: String parameter= [{"id":"pdTNKcY1YS55oG2M",.......}] 1. 关于net.sf.js ...

  7. 旧书重温:0day2【4】动态获取函数地址

    通过以上3篇文章的学习,我们已经可以获取到kernel32.dll的地址了下一步 我们就是获取几个重要的函数 1.GetProcAddress 2.LoadLibrary 有了这两个函数很多函数都可以 ...

  8. 如何快速上手.net下单元测试工具NUnit?

    NUnit基本使用 准备知识: 读此博文需要了解单元测试基本概念及NUnit的的安装. 传送门:单元测试之道(使用NUnit) 1.常见的错误 当学习一个新东西时,先学习错误,是最快的方式. 1.1 ...

  9. FZU Problem 2129 子序列个数

    看了 dp 方程之后应该是妙懂 每次 加入一个数,×2  然后剪掉重复的: 重复的个数 维前面那个数,,,,, #include<iostream> #include<stdio.h ...

  10. BZOJ - 5427:最长上升子序列 (二分&思维)

    现在给你一个长度为n的整数序列,其中有一些数已经模糊不清了,现在请你任意确定这些整数的值, 使得最长上升子序列最长.(为何最长呢?因为hxy向来对自己的rp很有信心)   Input 第一行一个正整数 ...