ConcurrentHashMap线程安全机制

put源码:

public V put(K key, V value) {return putVal(key, value, false);
}/** Implementation for put and putIfAbsent */
final V putVal(K key, V value, boolean onlyIfAbsent) {if (key == null || value == null) throw new NullPointerException();int hash = spread(key.hashCode());int binCount = 0;for (Node<K,V>[] tab = table;;) {Node<K,V> f; int n, i, fh;if (tab == null || (n = tab.length) == 0)tab = initTable();else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {if (casTabAt(tab, i, null,new Node<K,V>(hash, key, value, null)))break;                   // no lock when adding to empty bin}else if ((fh = f.hash) == MOVED)tab = helpTransfer(tab, f);else {V oldVal = null;synchronized (f) {if (tabAt(tab, i) == f) {if (fh >= 0) {binCount = 1;for (Node<K,V> e = f;; ++binCount) {K ek;if (e.hash == hash &&((ek = e.key) == key ||(ek != null && key.equals(ek)))) {oldVal = e.val;if (!onlyIfAbsent)e.val = value;break;}Node<K,V> pred = e;if ((e = e.next) == null) {pred.next = new Node<K,V>(hash, key,value, null);break;}}}else if (f instanceof TreeBin) {Node<K,V> p;binCount = 2;if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,value)) != null) {oldVal = p.val;if (!onlyIfAbsent)p.val = value;}}}}if (binCount != 0) {if (binCount >= TREEIFY_THRESHOLD)treeifyBin(tab, i);if (oldVal != null)return oldVal;break;}}}addCount(1L, binCount);return null;
}

源码解释:

这个函数是Java中ConcurrentHashMap类的putVal方法,用于在哈希表中插入键值对。函数使用了CAS(Compare and Swap)操作和同步锁来保证并发安全性。具体功能如下:
1、首先检查键值对是否为null,若为null则抛出NullPointerException。
2、计算键的哈希值并进行扩散(spread)操作。
3、使用for循环遍历哈希表,直到插入成功或遇到特定情况退出循环。
4、如果哈希表为空,则调用initTable方法初始化哈希表。
5、如果当前位置的节点为空,则使用CAS操作将新节点插入到空的位置。
6、如果当前位置的节点不为空且为MOVED(表示哈希表正在扩容),则调用helpTransfer方法帮助完成扩容操作。
7、如果当前位置的节点不为空且为链表或红黑树节点,则通过synchronized锁住头Node进行进一步的操作。
        遍历链表或红黑树,如果找到与给定键相等的节点,则更新节点的值,并在onlyIfAbsent为false时返回旧值。
        如果未找到相等的节点,则在链表尾部或红黑树中插入新节点。
8、如果插入操作成功,则根据binCount(桶计数)的值决定是否需要将链表转换为红黑树,并返回旧值。
9、最后,更新计数器并返回null。
该函数通过使用并发技术,实现了在多线程环境下对哈希表的高效插入操作。

关于CAS操作插入新节点:

CAS(Compare-And-Swap)是一种用于实现多线程同步的原子指令,广泛应用于现代计算机架构中。CAS操作包含三个主要参数:内存位置(V)、预期原值(A)和新值(B)。在执行操作时,CAS会原子性地执行以下步骤:

  1. 比较:首先比较内存位置V当前的值是否与预期原值A相等。
  2. 交换:如果相等,那么将内存位置V的值更新为新值B。
  3. 返回:如果内存位置V的当前值与预期原值A不相等,说明其他线程已经修改了这个值,那么CAS操作失败,不会执行更新。

Node节点源码:

使用了volatile使其可见,所以自旋判断时是否为预期值null,如果相等就插入,不相等就失败退出继续执行下一次putVal里的循环

总结:

通过CAS+volatile+synchronized锁住头节点三个功能共同作用保证了线程安全性

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/786965.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue快速入门(二)安装vue调试插件

教程很详细&#xff0c;直接上过程 上一篇 新增内容 在国内网站下载谷歌插件安装插件 点击跳转极简插件 此处我们以Chrome浏览器为例 到这里我们就成功安装了插件 使用上一篇博客的代码在浏览器F12调试一下 这样就可以使用了&#xff01;&#xff01;&#xff01;

云原生时代来了,遗留的虚拟机怎么办?红帽 OpenShift 虚拟化实现“稳敏兼得”

作者 | 宋慧 出品 | CSDN 从云原生、容器、微服务&#xff0c;到现在大热的 AIGC、GPU&#xff0c;越来越多的技术与架构正在进入数据中心与基础设施中&#xff0c;以服务数字化转型中的创新业务与应用。在成熟虚拟化传统&#xff08;稳态&#xff09;业务和容器、新&#xff…

Vue-05

v-model 应用于其他表单元素 常见的表单元素都可以用v-model绑定关联 → 快速获取或设置表单元素的值 它会根据控件类型自动选取正确的方法来更新元素 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name…

【PFA树脂交换柱】实验室高纯PFA材质过滤柱耐受电子级氢氟酸含氟树脂层析柱

PFA离子交换柱&#xff0c;也叫PFA层析柱、PFA过滤柱等&#xff0c;其原理是利用吸附剂对不同化合物有不同吸附作用和不同化合物在溶剂中的不同溶解度&#xff0c;用适应溶剂使混合物在填有吸附剂的柱内通过&#xff0c;使复杂的混合物达到分离和提纯的目的。 柱体为透明PFA材…

Centos7 elasticsearch-7.7.0 集群搭建,启用x-pack验证 Kibana7.4用户管理

前言 Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎&#xff0c;能够解决不断涌现出的各种用例。 作为 Elastic Stack 的核心&#xff0c;它集中存储您的数据&#xff0c;帮助您发现意料之中以及意料之外的情况。 环境准备 软件 …

【Linux】自定义协议+序列化+反序列化

自定义协议序列化反序列化 1.再谈 "协议"2.Cal TCP服务端2.Cal TCP客户端4.Json 喜欢的点赞&#xff0c;收藏&#xff0c;关注一下把&#xff01; 1.再谈 “协议” 协议是一种 “约定”。在前面我们说过父亲和儿子约定打电话的例子&#xff0c;不过这是感性的认识&a…

Kafka入门到实战-第二弹

Kafka入门到实战 Kafka快速开始官网地址Kafka概述Kafka术语Kafka初体验更新计划 Kafka快速开始 官网地址 声明: 由于操作系统, 版本更新等原因, 文章所列内容不一定100%复现, 还要以官方信息为准 https://kafka.apache.org/Kafka概述 Apache Kafka 是一个开源的分布式事件流…

【SQL Server】2. 将数据导入导出到Excel表格当中

最开始&#xff0c;博主介绍一下自己的环境&#xff1a;SQL Sever 2008 R2 SQL Sever 大致都差不多 1. 通过自带软件的方式 首先找到下载SQL Sever中提供的导入导出工具 如果开始界面没有找到自己下载的路径 C:\Program Files\Microsoft SQL Server\100\DTS\Binn下的DTSWiz…

整理开源资源:零代码开发灵魂——逻辑引擎,收藏吧

逻辑配置是零代码开发的业务核心功能&#xff0c;本质上是实现服务的编排&#xff0c;把原子的服务通过可视化编排&#xff0c;形成最终的业务逻辑。 经过小编的精心整理&#xff0c;把相关的资源全部汇总起来&#xff0c;收藏吧&#xff01; Drawflow 拖动节点多路输入/输出…

增强Java技能:使用OkHttp下载www.dianping.com信息

在这篇技术文章中&#xff0c;我们将探讨如何使用Java和OkHttp库来下载并解析www.dianping.com上的商家信息。我们的目标是获取商家名称、价格、评分和评论&#xff0c;并将这些数据存储到CSV文件中。此外&#xff0c;我们将使用爬虫代理来绕过任何潜在的IP限制&#xff0c;并实…

python3内置持久化模块shelve心得

python3内置持久化模块shelve心得 来自python官方网站的解释&#xff1a; https://docs.python.org/zh-cn/3.10/library/shelve.html 本文环境&#xff1a; Windows 10 专业版 64 位 Thonny 3.2.6 概述 内置模块 shelve 可以将任意 Python 对象&#xff08;即 https://docs…

基于FPGA的HDMI视频接口设计

HDMI介绍 HDMI(High-DefinitionMultimedia Interface)又被称为高清晰度多媒体接口,是首个支持在单线缆上传输,不经过压缩的全数字高清晰度、多声道音频和智能格式与控制命令数据的数字接口。HDMI接口由Silicon Image美国晶像公司倡导,联合索尼、日立、松下、飞利浦、汤姆逊、东…

LLM面面观之MoE

1. 背景 根据本qiang~最新的趋势观察&#xff0c;基于MoE架构的开源大模型越来越多&#xff0c;比如马斯克的Grok-1(314B), Qwen1.5-MoE-A2.7B等&#xff0c;因此想探究一下MoE里面的部分细节。 此文是本qiang~针对大语言模型的MoE的整理&#xff0c;包括原理、流程及部分源码…

Mybatis——查询数据

查询操作 根据用户id查询单条记录&#xff0c;在映射器接口(UserMapper)中定义如下方法&#xff1a; package org.example.mapper;import org.example.demo.User;import java.util.List;public interface UserMapper {//根据id查询UserUser selectUserById(Integer userId); …

stable diffusion 的 GPU 不足怎么解决

稳定扩散&#xff08;stable diffusion&#xff09;是一种用于图像处理和计算机视觉任务的图像滤波算法。 当使用Stable Diffusion过程中遇到GPU显示内存不足的问题时。解决这个问题的方法有以下几种&#xff1a; 目前&#xff0c;对我来说&#xff0c;就最后一点能够暂时解决当…

GaussDB云数据库极简版安装与使用-新手指南

一、前言 作为一款领先的企业级数据库管理系统&#xff0c;GaussDB 提供了强大的性能、高度可靠性和丰富的功能&#xff0c;是企业构建可靠、高性能的数据库解决方案的理想选择。 本文主要针对高校和个人测试环境&#xff0c;介绍极简版安装和使用过程&#xff0c;更加适合高…

SwiftUI Swift 选择图片 添加图片

1. 添加记帐时添加图片功能 2. Show me the code // // TestPhotoPicker.swift // pandabill // // Created by 朱洪苇 on 2024/3/30. //import SwiftUI import PhotosUI import Foundationstruct TestPhotoPicker: View {State private var selectedItem: PhotosPickerIt…

Php_Code_challenge12

题目&#xff1a; 答案&#xff1a; 解析&#xff1a; 字符串拼接。

文献阅读:通过 NeuronChat 从单细胞转录组推断神经元-神经元通信

文献介绍 「文献题目」 Inferring neuron-neuron communications from single-cell transcriptomics through NeuronChat 「研究团队」 聂青&#xff08;加利福尼亚大学欧文分校&#xff09; 「发表时间」 2023-02-28 「发表期刊」 Nature Communications 「影响因子」 16.6…

15 - grace序列处理 - 十三点滑动平均法

grace序列处理 -十三点滑动平均法 滑动平均是一种常用的平滑数据的方法,可以用于去除噪声或者提取趋势。十三点滑动平均是指使用窗口大小为13的滑动平均,应用于GRACE序列处理中可以去除周年项的影响。 十三点滑动平均的计算公式为: y [ n ] = ( x [ n − 6 ]