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

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

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. Web Service——CXF+Spring 整合

    结合spring框架来实现CXF发布SOAP协议的服务,步骤基本相同,所不同的是的多了一些配置项,步骤如下 1. 服务端 第一步:创建web项目(引入jar包) 第二步:创建SEI接口 import ...

  2. Codeigniter base_url() 返回的怎么是ip地址

    本篇文章由:http://xinpure.com/codeigniter-base-url-to-return-what-is-an-ip-address/ 简单说说情况 虽然也是有一段时间没有用过 ...

  3. 从零开始的 Python 爬虫速成指南

    序 本文主要内容:以最短的时间写一个最简单的爬虫,可以抓取论坛的帖子标题和帖子内容. 本文受众:没写过爬虫的萌新. 入门 0.准备工作 需要准备的东西: Python.scrapy.一个IDE或者随便 ...

  4. Oracle查询结果中:一列中相同的值或一列中重复的值,只显示一次

    http://www.itpub.net/thread-1768915-1-1.html 问题: CREATE TABLE test(ob_id VARCHAR(32),ob_name VARCHAR ...

  5. eclipse.ini的相关说明

    http://www.cnblogs.com/yan5lang/archive/2011/05/24/2055867.htmlEclipse的启动由$ECLIPSE_HOME/eclipse.ini控 ...

  6. 在Windows Service上安装运行Redis

    CSDN下载RedisWatcher,运行InstallWatcher.msi,默认安装在C:\Program Files (x86)\RedisWatcher,修改watcher.conf # re ...

  7. RHEL7 -- 通过gerp使用正则表达式

    正则表达式常会含有shell元字符(如S.*等),建议使用单引号('')来括起行令上的正则表达式 1.行定位符号 行首定位符号^和行尾定位符$ #找出以s开头的行: # grep '^s' /etc/ ...

  8. Linux内核中锁机制之RCU、大内核锁

    在上篇博文中笔者分析了关于完成量和互斥量的使用以及一些经典的问题,下面笔者将在本篇博文中重点分析有关RCU机制的相关内容以及介绍目前已被淘汰出内核的大内核锁(BKL).文章的最后对<大话Linu ...

  9. CodeForces 445B. DZY Loves Chemistry(并查集)

    转载请注明出处:http://blog.csdn.net/u012860063?viewmode=contents 题目链接:http://codeforces.com/problemset/prob ...

  10. 深入理解Docker Volume(一)

    想要了解Docker Volume,首先我们需要知道Docker的文件系统是如何工作的.Docker镜像是由多个文件系统(只读层)叠加而成.当我们启动一个容器的时候,Docker会加载镜像层并在其上添 ...