博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
concurrentHashmap实现原理
阅读量:6608 次
发布时间:2019-06-24

本文共 1228 字,大约阅读时间需要 4 分钟。

hot3.png

concurrentHashmap是java5支持 高并发、高吞吐量的线程安全HashMap实现.

实现原理:

允许多个修改并发进行,关键技术是锁分离。分为多个段(segment)来表示不同的部分,每个段就是一个小的hashtable,他们有自己的锁。

有些方法需要跨段,比如size()和containsValue(),它们可能需要锁定整个表而而不仅仅是某个段,这需要按顺序锁定所有段,操作完毕后,又按顺序释放所有段的锁。

1:首先看下get操作,同样ConcurrentHashMap的get操作是直接委托给Segment的get方法,直接看Segment的get方法.

读操作并不需要加锁。为了确保读操作能够看到最新的值,将value设置成volatile,这避免了加锁。

            static final class HashEntry<K,V> {  

                  final K key;  

                  final int hash;  

                  volatile V value;     

                  final HashEntry<K,V> next;  

            }

第一步是访问count变量,这是一个volatile变量,由于所有的修改操作在进行结构修改时都会在最后一步写count变量,通过这种机制保证get操作能够得到几乎最新的结构更新。对于非结构更新,也就是结点值的改变,由于HashEntry的value变量是volatile的,也能保证读取到最新的值。接下来就是对hash链进行遍历找到要获取的结点,如果没有找到,直接访回null。对hash链进行遍历不需要加锁的原因在于链指针next是final的。但是头指针却不是final的,这是通过getFirst(hash)方法返回,也就是存在table数组中的值。这使得getFirst(hash)可能返回过时的头结点,例如,当执行get方法时,刚执行完getFirst(hash)之后,另一个线程执行了删除操作并更新头结点,这就导致get方法中返回的头结点不是最新的。这是可以允许,通过对count变量的协调机制,get能读取到几乎最新的数据,虽然可能不是最新的。要得到最新的数据,只有采用完全的同步。

2:删除操作remove

获取段锁,先定位到段,然后委托段去执行删除操作。当多个删除操作并行时,只要不是在同一个段,就可以同时进行。

105747_9tmg_3027545.png

3:put

该方法也是在持有锁的情况下执行的,首先判断是否需要rehash,需要就先rehash。接着是找是否存在同样一个key的结点,如果存在就直接替换这个结点的值。否则创建一个新的结点并添加到hash链的头部,这时一定要修改modCount和count的值,同样修改count的值一定要放在最后一步。put方法调用了rehash方法,reash方法实现得也很精巧,主要利用了table的大小为2^n,这里就不介绍了

 

转载于:https://my.oschina.net/u/3027545/blog/1785477

你可能感兴趣的文章
第十周编程总结--助教
查看>>
iOS 代理的具体使用
查看>>
android7.0以上使用融云即使通讯的坑
查看>>
Java 组件化(gradle)
查看>>
String,StringBuffer与StringBuilder的区别
查看>>
poj1190生日蛋糕--DFS
查看>>
SSO单点登录 与 CAS
查看>>
Hibernate注解开发
查看>>
毕设之iframe跳转子页面问题
查看>>
查看证书
查看>>
sql server2008修改登录名下的默认架构名
查看>>
main方法无法编译
查看>>
指针与数组名
查看>>
Android Dialog(转)
查看>>
把所有事都做完的曙光终于出现在了地平线上
查看>>
C#读取XML文件中有乱码的处理办法
查看>>
Tensorflow Batch normalization函数
查看>>
前端:select选择框配合EL表达式
查看>>
xp的虚拟机如何访问本地主机上的文件
查看>>
ZOJ3623: Battle Ships(类完全背包)
查看>>