Java7和8中ConcurrentHashMap的区别

2019-07-03 00:00:00 concurrenthashmap 区别 java7

1. 初始化

在JAVA7中ConcurrentHashMap默认初始化时,会创建Segment数组,数组数量为16,数组成员1个,加载权值0.75,在Segment对象中,创建HashEntry数组,数组数量为2,没有数组成员。

《Java7和8中ConcurrentHashMap的区别》
《Java7和8中ConcurrentHashMap的区别》

在JAVA8中,ConcurrentHashMap默认初始化时,创建一个空对象。代码如下

《Java7和8中ConcurrentHashMap的区别》

2. 添加值

JAVA7是直接调用ConcurrentHashMap的put方法。JAVA7只对value是否为空判断。但是在hash时,还是会对空key抛出异常。

《Java7和8中ConcurrentHashMap的区别》

而JAVA8不仅对value判断空,对key也判断空。

《Java7和8中ConcurrentHashMap的区别》
《Java7和8中ConcurrentHashMap的区别》

对hash值也使用了不同的方法

JAVA7:

《Java7和8中ConcurrentHashMap的区别》
《Java7和8中ConcurrentHashMap的区别》

JAVA8:

《Java7和8中ConcurrentHashMap的区别》

寻找可以防止的Segment。
JAVA7使用哈希值的最高4位和1111做与(&)操作来确定位置。如果是空,先创建一个Segment,然后再创建一个HashEntry放入该Segment.

《Java7和8中ConcurrentHashMap的区别》

《Java7和8中ConcurrentHashMap的区别》
《Java7和8中ConcurrentHashMap的区别》

JAVA8先创建一个数组长度为16的Segment空数组,然后在用哈希值的最后4位和1111做与(&)操作来确定位置。如果是空,新建一个放入。

《Java7和8中ConcurrentHashMap的区别》
《Java7和8中ConcurrentHashMap的区别》

3. 分组方式不同

JAVA7中的ConcurrentHashMap使用Segment作为每个分组的对象,Segment中使用HashEntry组来作为存放数据的对象。

而JAVA8中的ConcurrentHashMap使用了轻量级的Node作为存放数据和分组的对象。通过链接的方式继续存放同样哈希值的对象。

4取值方式不同

JAVA7首先判断属于哪个Segment,然后再看该Segment的HashEntry集合—table是否为空。如果都不为空,就去HashEntry链里找对应的key,找到返回值。找不到就最终返回null。

《Java7和8中ConcurrentHashMap的区别》
《Java7和8中ConcurrentHashMap的区别》

JAVA8首先找到属于那个节点数组Node。然后先判断头结点是否就是该值,如果是返回。如果不是,利用链表特效往下寻找。

《Java7和8中ConcurrentHashMap的区别》
《Java7和8中ConcurrentHashMap的区别》

5. 删除方式不同

JAVA7删除键值。先是查找对应的Segment.

《Java7和8中ConcurrentHashMap的区别》
《Java7和8中ConcurrentHashMap的区别》

然后由Segment处理删除操作,因为Segment继承了ReentrantLock,所以有加锁能力。

先尝试获取锁,失败会等待。如果成功就开始删除操作。删除最后解除锁。

《Java7和8中ConcurrentHashMap的区别》
《Java7和8中ConcurrentHashMap的区别》

JAVA8则是通过哈希找到table中的Node链表头结点。

《Java7和8中ConcurrentHashMap的区别》
《Java7和8中ConcurrentHashMap的区别》

因为Node没有继承ReentrantLock/Lock,所以使用Synchronized来锁住整个链表。这里只截取部分代码。

《Java7和8中ConcurrentHashMap的区别》
《Java7和8中ConcurrentHashMap的区别》

    原文作者:无限可能
    原文地址: https://zhuanlan.zhihu.com/p/42934105
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。

相关文章