加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

ConcurrentHashMap 总结( 上 )

发布时间:2020-12-14 06:38:50 所属栏目:Java 来源:网络整理
导读:转自: p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; clear:both; min-height:1em; color:rgb(62,62,62); font-family:'Helvetica Neue',Helvetica,'Hiragino Sans GB','Microsoft YaHei',Arial,sans-serif; font-siz

转自:

<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; clear:both; min-height:1em; color:rgb(62,62,62); font-family:'Helvetica Neue',Helvetica,'Hiragino Sans GB','Microsoft YaHei',Arial,sans-serif; font-size:16px; max-width:100%!important; word-wrap:break-word!important">
并发编程实践中,ConcurrentHashMap是一个经常被使用的数据结构,相比于Hashtable以及Collections.synchronizedMap(),ConcurrentHashMap在线程安全的基础上提供了更好的写并发能力,但同时降低了对读一致性的要求(这点好像CAP理论啊 O(∩_∩)O)。ConcurrentHashMap的设计与实现非常精巧,大量的利用了volatile,final,CAS等lock-free技术来减少锁竞争对于性能的影响,无论对于Java并发编程的学习还是Java内存模型的理解,ConcurrentHashMap的设计以及源码都值得非常仔细的阅读与揣摩。


<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; clear:both; min-height:1em; color:rgb(62,sans-serif; font-size:16px; max-width:100%!important; word-wrap:break-word!important">
<br style="margin:0px; padding:0px; max-width:100%!important; word-wrap:break-word!important">


<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; clear:both; min-height:1em; color:rgb(62,sans-serif; font-size:16px; max-width:100%!important; word-wrap:break-word!important">
这篇日志记录了自己对ConcurrentHashMap的一些总结,由于JDK6,7,8中实现都不同,需要分开阐述在不同版本中的ConcurrentHashMap。


<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; clear:both; min-height:1em; color:rgb(62,sans-serif; font-size:16px; max-width:100%!important; word-wrap:break-word!important">
之前已经在<a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MjM5NzMyMjAwMA==&amp;mid=206418539&amp;idx=1&amp;sn=988343c3d0580f8e0af2a65230e8ff34&amp;scene=21#wechat_redirect" rel="nofollow" style="margin:0px; padding:0px; color:rgb(96,127,166); text-decoration:none; max-width:100%!important; word-wrap:break-word!important">ConcurrentHashMap原理分析中解释了ConcurrentHashMap的原理,主要是从代码的角度来阐述是源码是如何写的,本文仍然从源码出发,挑选个人觉得重要的点(会用红色标注)再次进行回顾,以及阐述ConcurrentHashMap的一些注意点。


<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; clear:both; min-height:1em; color:rgb(62,sans-serif; font-size:16px; max-width:100%!important; word-wrap:break-word!important">
<span style="margin:0px; padding:0px; max-width:100%!important; word-wrap:break-word!important"><span style="margin:0px; padding:0px; max-width:100%!important; word-wrap:break-word!important; color:rgb(255,76,65)">1. JDK6与JDK7中的实现


<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; clear:both; min-height:1em; color:rgb(62,sans-serif; font-size:16px; max-width:100%!important; word-wrap:break-word!important">
<span style="margin:0px; padding:0px; max-width:100%!important; word-wrap:break-word!important"><span style="margin:0px; padding:0px; max-width:100%!important; word-wrap:break-word!important; color:rgb(123,12,0)">1.1 设计思路


<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; clear:both; min-height:1em; color:rgb(62,sans-serif; font-size:16px; max-width:100%!important; word-wrap:break-word!important">
ConcurrentHashMap采用了分段锁的设计,只有在同一个分段内才存在竞态关系,不同的分段锁之间没有锁竞争。相比于对整个Map加锁的设计,分段锁大大的提高了高并发环境下的处理能力。但同时,由于不是对整个Map加锁,导致一些需要扫描整个Map的方法(如size(),containsValue())需要使用特殊的实现,另外一些方法(如clear())甚至放弃了对一致性的要求(ConcurrentHashMap是弱一致性的,具体请查看<span style="margin:0px; padding:0px; max-width:100%!important; word-wrap:break-word!important; color:rgb(255,104,39)">ConcurrentHashMap能完全替代HashTable吗?)。


<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; clear:both; min-height:1em; color:rgb(62,sans-serif; font-size:16px; max-width:100%!important; word-wrap:break-word!important">
<br style="margin:0px; padding:0px; max-width:100%!important; word-wrap:break-word!important">


<blockquote style="margin:0px; padding:0px 0px 0px 10px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(219,219,219); color:rgb(62,sans-serif; font-size:16px; max-width:100%!important; word-wrap:break-word!important">
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; clear:both; min-height:1em; max-width:100%!important; word-wrap:break-word!important">
<span style="margin:0px; padding:0px; max-width:100%!important; word-wrap:break-word!important; font-size:12px; color:rgb(136,136,136)">http://my.oschina.net/hosee/blog/675423

JDK7与JDK8中HashMap的实现)的结构,即内部拥有一个Entry数组,数组中的每个元素又是一个链表;同时又是一个ReentrantLock(Segment继承了ReentrantLock)。ConcurrentHashMap中的HashEntry相对于HashMap中的Entry有一定的差异性:HashEntry中的value以及next都被volatile修饰,这样在多线程读写过程中能够保持它们的可见性,代码如下:

{

next;

)UNSAFE.getObjectVolatile(ss,u))

s = new Segment(lf,threshold,tab);

node) {

[] oldTable = table;

[]) new HashEntry[newCapacity];

e = oldTable[i];

next = e.next;

lastRun = e;

last = next;

n = newTable[k];

(h,p.key,v,n);

[] table;

类,也就是说TreeNode带有next指针,这样做的目的是方便基于TreeBin的访问。

extends Node[] nextTable;

[] tab) {

find(int h,Object k) {

[] tab = nextTable;;) {

e; int n;

)e).nextTable;

k = ConcurrentHashMap.class;

ck = CounterCell.class;

ak = Node[].class;

Node tabAt(Node[] tab,int i) {

)U.getObjectVolatile(tab,((long)i << ASHIFT) + ABASE);

c,Node v) {

[] initTable() {

0) ? sc : DEFAULT_CAPACITY;

[] nt = (Node[])new Node[n];

>> 2);//相当于0.75*n 设置一个扩容的阈值

  • =0),如果它是一个链表的头节点,就构造一个反序链表,把他们分别放在nextTable的i和i+n的位置上

  • (编辑:李大同)

    【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

      推荐文章
        热点阅读