【转】ConcurrentMap 分析和思考

预备知识: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 分析和思考

时间: 2024-10-12 09:14:30

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

跨链技术的分析和思考

当前的区块链底层技术平台百花齐放,不同的业务.不同的技术底层的区块链之间缺乏统一的互联互通的机制,这极大限制了区块链技术和应用生态的健康发展.跨链的需求由此而来,本文通过分析几种主流的跨链方案探讨跨链技术的本质及相应的解决思路. ## 跨链的类型 跨链交互根据所跨越的区块链底层技术平台的不同可以分为同构链跨链和异构链跨链:同构链之间安全机制.共识算法.网络拓扑.区块生成验证逻辑都一致,它们之间的跨链交互相对简单.而异构链的跨链交互相对复杂,比如比特币采用PoW算法而联盟链Fabric采用传统确定

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

http://mogu.io/156-156 摘要 本文一是为了讨论在Linux系统出现问题时我们能够借助哪些工具去协助分析,二是讨论出现问题时大致的可能点以及思路,三是希望能给应用层开发团队介绍一些Linux内核机制从而选择更合适的使用策略. 前言 搜索团队的服务器前段时间频繁出现CPU load很高(比如load average达到80多)的情况,正所谓术业有专攻,搜索的兄弟们对Linux底层技术理解的不是很深入,所以这个问题困扰了他们一段时间. 相信我们在遇到问题时都有类似的经历,如果这个

黑马程序员--关于交通灯管理系统的分析和思考

------- <a href="http://www.itheima.com" target="blank">android培训</a>.<a href="http://www.itheima.com" target="blank">java培训</a>.期待与您交流! ---------- 1. 交通灯管理系统的项目需求 (1).异步随机生成按照各个路线行驶的车辆 (2).信

反编译C程序为汇编代码,汇编代码执行过程的分析与思考

张韩+ 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 系统:32位Ubuntu14.04 编写C程序:(保存至main.c) int g(int x) {   return x + 3; } int f(int x) {   return g(x); } int main(void) {   return f(8) + 1; } 控制台反编译命令: 得到main.s,其内容如下:

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

[前言] 自腾讯与京东建立了战略合作关系之后,笔者网上购物就首选京东了.某天在家里访问京东首页的时候突然吃惊地发现浏览器突然跳到了第三方网站再回到京东,心里第一个反应就是中木马了. 竟然有这样的事,一定要把木马大卸八块. [原因排查] 首先在重现的情况下抓包,京东官网确实返回了一段Java让浏览器跳转到了yiqifa.com. 下图是应用层的抓包. 服务器返回的代码导致跳转,基本可以排除本地木马,推测是网络或者服务器的问题.根据笔者的经验,这种情况很大可能是链路上的流量劫持攻击.当然也不能排除京

memcache redundancy机制分析及思考

设计和开发可以掌控客户端的分布式服务端程序是件幸事,可以把很多事情交给客户端来做,而且可以做的很优雅.角色决定命运,在互联网架构中,web server必须冲锋在前,注定要在多浏览器版本以及协议兼容性方面呕心沥血.但要是做了web server的backend,就会好很多,可以让服务端程序独善其身,分布式的功能特性都由客户端来支持和实现.memcache就是这样的设计模式.memcache是后台架构必备的利器,关于其原理及源码分析可以直接google之,在此不再多说.最近项目中要考虑冗余和容错的

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

之前,在用ENode开发forum案例时,遇到了关于如何实现论坛帖子的回复的统计信息如何更新的问题.后来找到了自己认为比较合理的解决方案,分享给大家.也希望能和大家交流,擦出更多的火花. 论坛核心领域问题分析 论坛领域的核心概念是:帖子.回复.大家都知道,一个帖子可以有零个或多个回复.对同一个帖子,不同的人可以并行发表回复.回复发表后,查看帖子详情时,可以根据回复的发表时间排序显示:此外,我们还关心某个帖子的最新发表的回复.最新回复的作者.最新回复时间,以及总回复数. 我们设计的系统,应该在实现

分享我对代码命名的一点思考和理解

一个软件最后都会落实到代码,而代码,其背后的架构设计或设计思想或模式固然重要,但我觉得更重要的东西则是良好的命名.混乱或错误的命名不仅让我们对代码难以理解,更糟糕的是,会误导我们的思维,导致对代码的理解完全错误.相反,良好的命名,则可以让我们的代码非常容易读懂,也能向读者正确表达事物以及逻辑的本质,从而使得代码的可维护性就大大增强. 另外一点也许大家还没感受到,那就是良好的命名,以及良好的命名习惯,由于我们总是对每个概念的名称要求非常苛刻,我们会思考这个名称所表达的概念是否正确,该名称是否正确表

短视频APP+不同类型社交应用发展分析+化妆品电商

短视频APP——昙花一现还是发展趋势? 在这个互联网与科技并行且飞速发展的时代,各种app不断涌入市场,其中短视频app便是一个典型,美拍,就成功入围2014年十大最火app.而短视频app也势必要成为发展趋势而绝非昙花一现,接下来就让我们一起分析一下它之所以能够引领时代潮流的种种原因. (一)时代背景 1.当前网络上的传播媒体十分多样,诸如微信,微博,QQ等都能够随时随地让人们分享自己的幸福,展示自己的风采,这样一来,便为短视频app提供了更广阔的交流发布空间. 2.短视频app的种类多种多样