ConcurrentHashMap

目标:

1.capacity,concurrencyLevel:容量与并发级别的,如何促发扩容,ConcurrentHashMap两个字段的意义:segmentMask,segmentShift

2.jdk1.6/jdk1.7不同之处,jdk1.6

count是volitile的

3.理解ConcurrentHashMap为何支持高并发,对此作了哪些优化,segment, volitile, happens-before, HashEntry final value?

4.记住默认容量、并发级别、加载因子

5.测试不同并发级别下的性能测试,出测试结果

6.实现一个简易的ConcurrentHashMap示例


总结:

1、字段的含义:

1.1 capacity是指整个map的容量,即所有segment中的hashEntry的数,map最终都是在hashEntry的中存储数据的

1.2 concurrencyLevel:并发级别,即ConcurrentHashMap中segment的数量,concurrencyLevel = segmentSize,并发时锁的即是segment,segmentSize 必须是 2^n ,可以参考HashMap的size也是必须是2^n

1.3 segmentShift,segmentMask:segment偏移量,segment掩码,在segmentFor时用到,定位到具体某个segment。segmentMask = segmentSize - 1,segmentShift= 32 - sshift,

sshift=n,n是segmentSize =

2^n中的n

如concurrencyLevel = 16 => sshift=4,segmentMask=15 =>

segmentShift= 32 - 4,再哈希后的数最大是32位二进制数据,所以是32 -

sshift,segmentFor:

hash >>> segmentShift & segmentMask 意思是让高4位参与到hash运算中

2、jdk1.6/jdk1.7: https://my.oschina.net/hosee/blog/675884

最大的区别在于,jdk1.6应用volatile关键字 happens-before原则实现的读/写一直,jdk1.6中用的UNSAFE的原子操作来实现的

3、高并发的原理

3.1 分离锁

无需锁整个ConcurrentHashMap,只在修改结构的时候,只需锁住分段segment

3.2 用 volatile 变量协调读写线程间的内存可见性,使得读(get)可以不加锁

读操作的高效之处在于整个get过程不需要加锁,除非读到的值是空的才会加锁重读。get操作是如何做到不加锁的呢?原因是它的get方法里将要使用的共享变量都定义成volatile,如用于统计当前Segement大小的       count字段和用于存储值的HashEntry的value。定义成volatile的变量,能够在线程之间保持可见性,能够被多线程同时读,并且保证不会读到过期的值,但是只能被单线程写(有一种情况可以被多线程写,就是写入的值不依赖于原值),在get操作里只需要读不需要写共享变量count和value,所以可以不用加锁。之所以不会读到过期的值,是根据java内存模型的happen before原则,对volatile字段的写入操作先于读操作,即使两个线程同时修改和获取volatile变量,get操作也能拿到最新的值,这是用volatile替换锁的经典应用场景(这是JDK1.6的实现)transient

volatile int count;volatile V value;

3.3 用 HashEntery 对象的不变性来降低读操作对加锁的需求

HashEntry 中的 key,hash,next 都声明为 final。这意味着,不能把节点添加到链接的中间和尾部,也不能在链接的中间和尾部删除节点。这个特性可以保证:在访问某个节点时,这个节点之后的链接不会被改变。这个特性可以大大降低处理链表时的复杂性。

3.4 总结

基于通常情形而优化:

在实际的应用中,散列表一般的应用场景是:除了少数插入操作和删除操作外,绝大多数都是读取操作,而且读操作在大多数时候都是成功的。正是基于这个前提,ConcurrentHashMap 针对读操作做了大量的优化。通过 HashEntry 对象的不变性和用 volatile型变量协调线程间的内存可见性,使得大多数时候,读操作不需要加锁就可以正确获得值。这两个特性相配合,不仅减少了请求同一个锁的频率(读操作一般不需要加锁就能够成功获得值),也减少了持有同一个锁的时间(只有读到 value 域的值为 null 时 , 读线程才需要加锁后重读)

ConcurrentHashMap 的高并发性主要来自于三个方面:

用分离锁实现多个线程间的更深层次的共享访问。

用 HashEntery 对象的不变性来降低执行读操作的线程在遍历链表期间对加锁的需求。

通过对同一个Volatile 变量的写 / 读访问,协调不同线程间读/ 写操作的内存可见性

4、默认容量:

DEFAULT_INITIAL_CAPACITY

= 16;

DEFAULT_CONCURRENCY_LEVEL

= 16;

DEFAULT_LOAD_FACTOR = 0.75f;

MAXIMUM_CAPACITY

= 1 << 30;

MAX_SEGMENTS =

1 << 16;

5、?Google ConcurrentHashMapperformancetest

6、?


参考:

Jdk1.6

http://www.infoq.com/cn/articles/ConcurrentHashMap/

https://www.ibm.com/developerworks/cn/java/java-lo-concurrenthashmap/

jdk1.7

https://my.oschina.net/hosee/blog/639352

https://my.oschina.net/hosee/blog/675884/

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,875评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,569评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,475评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,459评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,537评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,563评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,580评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,326评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,773评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,086评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,252评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,921评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,566评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,190评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,435评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,129评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,125评论 2 352

推荐阅读更多精彩内容