预备知识:Java HashMap and HashSet 的实现机制

由预备知识可以知道hashmap 的存储结构为:

(图像来自http://www.ibm.com/developerworks/cn/java/j-lo-hash/

也是说:一个hashmap 内部含有一个Entity 类行的数组,这个数组中的元素都是Entity。实际上我们放入map 中的key 和 value 就对应一个Entity 对象,这个Entity 对象包含一个key、value、hashcode(key 的)和一个Entity 的引用,通过这个引用,Entity 可以形成一个链表。在图中,蓝色矩形方框代表数组,橙色椭圆代表Entity 对象。

注意HashMap 类不是线程安全的。

ConcurrentMap  主要的子类是ConcurrentHashMap。

原理:一个ConcurrentHashMap 由多个segment 组成,每个segment 包含一个Entity 的数组。这里比HashMap 多了一个segment 类。该类继承了ReentrantLock 类,所以本身是一个锁。当多线程对ConcurrentHashMap 操作时,不是完全锁住map, 而是锁住相应的segment 。这样提高了并发效率。

构造函数的分析:

  /** 

     * Creates a new, empty map with a default initial capacity (16), 

     * load factor (0.75) and concurrencyLevel (16). 

     */  

  public ConcurrentHashMap() {  

    this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL);  

    }  

这是ConcurrentHashMap 的无参构造函数,可以看到默认大小为16,负载因子0.75,并发级别为16.

Put 函数的分析:

  /** 

     * 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 

     */  

  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);  

    }  

可以看出通过hash() 函数得到key 的哈希值,在得到相应的segment,在通过segment 存储Entity。

同时为了避免“检测再修改”(有条件线程安全参见[2])等并发问题,ConcurrentHashMap 提供了putIfAbsent(K key, V value)  方法,当key 不存在时,添加。(key 的存在靠两个条件,一个是key的hashcode方法,另外一个是key 的equal 方法)

优点:由于对对应segment  加锁,而不是锁定整个map,并发性得到了提高。能够直接提高插入、检索以及移除操作的可伸缩性。

缺点:当遍历map 中的元素时,需要获取所有的segment 的锁,使用遍历时慢。锁的增多,占用了系统的资源。使得对整个集合进行操作的一些方法(例如 size() 或 isEmpty() )的实现更加困难,因为这些方法要求一次获得许多的锁,并且还存在返回不正确的结果的风险。

【转】ConcurrentMap 分析和思考的更多相关文章

  1. 我对Padding Oracle Attack的分析和思考

    道哥的<白帽子讲web安全>有一章提到Padding Oracle Attack的攻击方式,据说这货在2011年的Pwnie Rewards上还被评为"最具价值的服务器漏洞&qu ...

  2. Linux内核分析:页回收导致的cpu load瞬间飙高的问题分析与思考--------------蘑菇街技术博客

    http://mogu.io/156-156 摘要 本文一是为了讨论在Linux系统出现问题时我们能够借助哪些工具去协助分析,二是讨论出现问题时大致的可能点以及思路,三是希望能给应用层开发团队介绍一些 ...

  3. 关于 SSV-ID: 4474 POC的分析和思考

    SSV-ID: 4474 SSV-AppDir: Discuz!漏洞 发布时间: 2008-11-21 (GMT+0800) URL:http://sebug.net/vuldb/ssvid-4474 ...

  4. Linux-某电商网站流量劫持案例分析与思考

    [前言] 自腾讯与京东建立了战略合作关系之后,笔者网上购物就首选京东了.某天在家里访问京东首页的时候突然吃惊地发现浏览器突然跳到了第三方网站再回到京东,心里第一个反应就是中木马了. 竟然有这样的事,一 ...

  5. memcache redundancy机制分析及思考

    设计和开发可以掌控客户端的分布式服务端程序是件幸事,可以把很多事情交给客户端来做,而且可以做的很优雅.角色决定命运,在互联网架构中,web server必须冲锋在前,注定要在多浏览器版本以及协议兼容性 ...

  6. WEB项目日志分析系统思考

    一.为什么需要日志分析系统 对ETL系统中数据转换和存储操作的相关日志进行记录以及实时分析有助于我们更好的观察和监控ETL系统的相关指标(如单位时间某些操作的处理时间),发现系统中出现的缺陷和性能瓶颈 ...

  7. 关于MySQL集群架构优劣势与适用场景的分析与思考

    http://blog.itpub.net/25723371/viewspace-1977389/

  8. datax分析与思考(一)

    Datax 总体流程图 先看执行的第一个步骤: 在最上层抽象类,这个里面相当于获取全局公共信息,java入口部分就是这个Engine的main方法直接启动 Engine 启动 com.alibaba. ...

  9. DDD实践问题之 - 关于论坛的帖子回复统计信息的更新的思考

    之前,在用ENode开发forum案例时,遇到了关于如何实现论坛帖子的回复的统计信息如何更新的问题.后来找到了自己认为比较合理的解决方案,分享给大家.也希望能和大家交流,擦出更多的火花. 论坛核心领域 ...

随机推荐

  1. Hibernate学习6—Hibernate 映射类型

    第一节:基本类型映射 com.cy.model.Book.java: package com.cy.model; import java.sql.Blob; import java.util.Date ...

  2. (转)CentOS 7安装Zabbix 3.4

    (转)Zabbix 3.4 支持Centos 7.貌似不支持6.9. 更多详细内容请参考官方说明文档,详细的安装要求不贴出来了. https://www.zabbix.com/documentatio ...

  3. oracle 中GROUP BY的用法

    转自:http://blog.csdn.net/basenet855x/article/details/6694150 问题: select item.itemnum,item.in1,item.in ...

  4. 【POJ】2329 Nearest number - 2(搜索)

    题目 传送门:QWQ 分析 在dp分类里做的,然而并不会$ O(n^3) $ 的$ dp $,怒写一发搜索. 看起来是$ O(n^4) $,但仔细分析了一下好像还挺靠谱的? poj挂了,没在poj交, ...

  5. win系统主机上的虚拟机NAT模式可修改3389端口做远程登录

    当你只有一个公网IP的时候,那么这个IP基本上是要分给物理主机的,那么本机的虚拟机就只能选NAT网络模式了,那么想在外网直接远程虚拟机的话,修改虚拟机的远程登录端口(不修改也可以,主要是主机的3389 ...

  6. Mysql本地服务器安装

    1.下载并解压 2.新建my.ini my.ini内容如下(路径填写自己的): ------------------------------------------------------------ ...

  7. oracle查看登录到oracle服务器的客户端ip

    1. 在sys模式下创建一个表,用于记录客户端登录数据库服务器的详细信息. 1 create table login_history 2 ( 3 username varchar2(60), --用户 ...

  8. C#对Excel的图文操作

    1.打印Excel 目前的商业工具如水晶报表,ActiveReport等,都提供了灵活,强大的功能,但是对于比较特殊化的表格,特别是国内的一些应用,都是一个个的格子组成的,这样要是用线来一根根画就比较 ...

  9. Nodejs&Express

    http://www.expressjs.comhttp://github.com/lelandtseng/form-datahttp://github.com/lelandtseng/mongo-m ...

  10. DDoS攻防战 (四):CC攻击防御系统部署

    1. 系统效果 此DDOS应用层防御系统已经部署在了http://www.yfdc.org网站上(如果访问失败,请直接访问位于国内的服务器http://121.42.45.55进行在线测试). 此防御 ...