Java7和8中ConcurrentHashMap的区别
1. 初始化
在JAVA7中ConcurrentHashMap默认初始化时,会创建Segment数组,数组数量为16,数组成员1个,加载权值0.75,在Segment对象中,创建HashEntry数组,数组数量为2,没有数组成员。
在JAVA8中,ConcurrentHashMap默认初始化时,创建一个空对象。代码如下
2. 添加值
JAVA7是直接调用ConcurrentHashMap的put方法。JAVA7只对value是否为空判断。但是在hash时,还是会对空key抛出异常。
而JAVA8不仅对value判断空,对key也判断空。
对hash值也使用了不同的方法
JAVA7:
JAVA8:
寻找可以防止的Segment。
JAVA7使用哈希值的最高4位和1111做与(&)操作来确定位置。如果是空,先创建一个Segment,然后再创建一个HashEntry放入该Segment.
JAVA8先创建一个数组长度为16的Segment空数组,然后在用哈希值的最后4位和1111做与(&)操作来确定位置。如果是空,新建一个放入。
3. 分组方式不同
JAVA7中的ConcurrentHashMap使用Segment作为每个分组的对象,Segment中使用HashEntry组来作为存放数据的对象。
而JAVA8中的ConcurrentHashMap使用了轻量级的Node作为存放数据和分组的对象。通过链接的方式继续存放同样哈希值的对象。
4取值方式不同
JAVA7首先判断属于哪个Segment,然后再看该Segment的HashEntry集合—table是否为空。如果都不为空,就去HashEntry链里找对应的key,找到返回值。找不到就最终返回null。
JAVA8首先找到属于那个节点数组Node。然后先判断头结点是否就是该值,如果是返回。如果不是,利用链表特效往下寻找。
5. 删除方式不同
JAVA7删除键值。先是查找对应的Segment.
然后由Segment处理删除操作,因为Segment继承了ReentrantLock,所以有加锁能力。
先尝试获取锁,失败会等待。如果成功就开始删除操作。删除最后解除锁。
JAVA8则是通过哈希找到table中的Node链表头结点。
因为Node没有继承ReentrantLock/Lock,所以使用Synchronized来锁住整个链表。这里只截取部分代码。
原文地址: https://zhuanlan.zhihu.com/p/42934105
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
相关文章