ConcurrentHashMap ——put()
2024-05-14 14:22:10 1 举报
ConcurrentHashMap的put()方法用于将键值对插入到哈希表中。与其他HashMap实现不同,ConcurrentHashMap通过使用分段锁来实现线程安全,以允许多个线程在同一时间对不同的段进行修改。在put()方法中,键和值首先会被包装为节点,然后使用哈希函数计算出插入位置。如果该位置为空,则新节点将被直接插入。否则,将检查是否存在相同键的节点,如果存在,更新该节点的值为新值。最后,将修改计数器加1,以触发可能的重新哈希和调整大小。这个方法在多线程环境下表现良好,但在单线程环境下,其性能可能不如普通的HashMap。
作者其他创作
大纲/内容
否
是
定位数组下标(table.len -1)& hash
链表结构
创建Node数组
NullPointerException
(sc = sizeCtl) < 0
判断下标元素 f 的hash fh==-1【MOVED】
从头结点开始遍历,每遍历一次,binCount+1
key,value判空
【MOVED】表示当前数组正在进行扩容,则需要当前线程帮忙迁移数据
putTreeVal
sizeCtl:默认为0 -1 时,说明有其它线程正在对表进行初始化操作<-1 时,用来表示当前有几个线程正在帮助扩容表初始化成功后,又会把它设置为扩容阈值
替换
table == null || table.len==0
计算hash
遍历到了为节点,插入尾节点
树节点
线程会让出CPU执行权,让自己或者其它的线程运行
sizeCtl设置为扩容阈值sc = n - (n >>> 2);sizeCtl = sc;
帮忙迁移数据helpTransfer()
put
判断首节点的hash fh>=0
判断首节点是否是TreeBin
TreeBin 对TreeNode的封装
初始化initTable()
Thread.yield()
initTable()
hash =spread(key.hashCode())
有和当前key相同的节点
CAS操作设置sizeCtl为-1
例如像初始化数组,完成之后就需要进入到下一次循环再put
synchronized加锁,给桶的第一个节点加锁
数据下标元素 f 是否为空
CAS 操作设置值
结束循环
无变化
recheck桶的第一个节点f无变化
循环操作
如果链表上的元素超过8,则转换为红黑树
synchronized同步锁内部操作
收藏
0 条评论
回复 删除
下一页