ConcurrentHashMap源码学习
实现接口
? ? ? ?ConcurrentMap(Map的基础方法)、Serializable(序列化)
基础属性
最大容量:2^30
默认容量:16
?常用方法
PUT
调用PutVal方法进行插入。
判断key或value是否为空:
是:抛出空指针一场
否:将key的哈希值的上下16位进行异或,是哈希值更散列
????????判断节点数组是否为空:
? ? ? ? 是:初始化节点数组,并将容量恢复至默认容量16
? ? ? ? 否:利用tabAt方法获取hash分配位置的值,如果节点值为null,则利用casTabAt方法将新节点插入到当前位置
? ? ? ? 否:hash分配位置的Hash值为-1(转发节点),则调用helpTransfer方法(在调整大小中进行传输)
? ? ? ? 否:onlyIfAbsent为true,hash分配位置的节点与插入节点的key相同,且value不为null,返回当前hash位置的value;
? ? ? ? 否:给到当前位置节点加锁,判断当前位置节点是否改变
? ? ? ? ? ? ? ? 否:当前位置的hash值是否大于等于0(表示正常节点哈希的可用位),寻找key是否已存在,已存在则判断onlyIfAbsent是否为false,寻找过程中binCount(链表深度)会随着每一次循环加1
? ? ? ? ? ? ? ? ? ? ? ? 是:将目标值替换旧值
? ? ? ? ? ? ? ? ? ? ? ? break跳出循环;
? ? ? ? ? ? ? ? ? ? ? ? 不存在则将目标节点添加到末尾
? ? ? ? ? ? ? ? 如果当前hash位置的节点是树类型的节点,调用putTreeVal方法来查找和插入节点(先判断节点是否存在,存在则返回节点,不存在则插入当前节点并返回null),返回值不为null则判断onlyIfAbsent是否为false
????????????????????????是:将目标值替换旧值
????????????????????????break跳出循环;
? ? ? ? ? ? ? ? 如果当前hash位置的节点是ReservationNode类型则抛出异常
throw new IllegalStateException("Recursive update")
? ? ? 如果binCount不等于0
? ? ? ? ? ? ? ? binCount大于8:将所有节点转换成树节点
? ? ? ? ? ? ? ? 旧值(相同key)不为null,返回旧值。
调用account将binCount添加到计数中,为下次调整做准备。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!