Java系列-ConcurrentHashMap源码-putVal

1.putVal

cas+自旋保证线程安全

处理某个槽位时使用synchronized

public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>implements ConcurrentMap<K,V>, Serializable {static final <K,V> Node<K,V> tabAt(Node<K,V>[] tab, int i) {return (Node<K,V>)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE);}static final <K,V> boolean casTabAt(Node<K,V>[] tab, int i,Node<K,V> c, Node<K,V> v) {return U.compareAndSwapObject(tab, ((long)i << ASHIFT) + ABASE, c, v);}  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) {//tab[i]//创建Node,放到tab[i]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) { //对tab[i]加锁if (tabAt(tab, i) == f) {if (fh >= 0) {//hash>=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;//找到key一样的节点,更新valif (!onlyIfAbsent){e.val = value;}break;}Node<K,V> pred = e;if ((e = e.next) == null) {//遍历到链表结尾也没有key相等的//放到链表尾pred.next = new Node<K,V>(hash, key, value, null);break;}}} else if (f instanceof TreeBin) {//如果是treeNode<K,V> p;binCount = 2;if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,value)) != null) {oldVal = p.val;if (!onlyIfAbsent){p.val = value;}}} else if (f instanceof ReservationNode){throw new IllegalStateException("Recursive update");}}}if (binCount != 0) {//看是否需要扩容if (binCount >= TREEIFY_THRESHOLD){treeifyBin(tab, i);}if (oldVal != null){return oldVal;}break;}}}addCount(1L, binCount);//维护size和看是否需要扩容return null;}
}

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

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

相关文章

President‘s Office

题目名字 President’s Office 题目链接 题意 .查找总统位置周围的桌子的数量&#xff0c;如果这个桌子是同一个颜色的&#xff0c;视作一个桌子不进行叠加&#xff1b; 思路 先定义总统桌子周围四个方位&#xff0c;进行计算然后循环输入之后确认总统的位置&#xff0c;进行…

使用AppleScript自动滚动预览

天冷了&#xff0c;在Mac预览里看PDF时&#xff0c;滚动页面非常冻手。预览虽然能够实现幻灯片播放&#xff0c;但是不支持逐行滚动。这里我们使用AppleScript来控制页面的滚动。 我们先将页面分成指定行数linesOfPage&#xff0c;根据自己的阅读速度设定滚动时间间隔intval。…

vue中实现使用相框点击拍照,canvas进行前端图片合并下载

拍照和相框合成,下载图片dome 一、canvas介绍 Canvas是一个HTML5元素,它提供了一个用于在网页上绘制图形、图像和动画的2D渲染上下文。Canvas可以用于创建各种图形,如线条、矩形、圆形、文本等,并且可以通过JavaScript进行编程操作。 Canvas元素本身是一个矩形框,可以通…

D3132|贪心算法

435.无重叠区间 初始思路&#xff1a; 我的思路就是如果有两个区间重叠&#xff0c;保留end比较小的那个区间&#xff0c;删除end比较大的区间。 class Solution {public int eraseOverlapIntervals(int[][] intervals) {Arrays.sort(intervals, new Comparator<int[]>…

在金属/绝缘体/p-GaN栅极高电子迁移率晶体管中同时实现大的栅压摆幅和增强的阈值电压稳定性

标题&#xff1a;Simultaneously Achieving Large Gate Swing and Enhanced Threshold Voltage Stability in Metal/Insulator/p-GaN Gate HEMT (IEDM2023) 摘要 摘要&#xff1a;对于增强型GaN功率晶体管的发展&#xff0c;栅压摆幅和阈值电压稳定性通常是互相排斥的。本文展…

Java小案例-RocketMQ的11种消息类型,你知道几种?(请求应答消息)

前言 Rocket的请求应答消息是指在使用Rocket&#xff08;这里可能是RocketMQ或者Rocket框架&#xff09;进行通信时&#xff0c;客户端发送一个请求到服务端&#xff0c;然后服务端处理该请求并返回一个响应的过程中的数据交换。 在RocketMQ中&#xff1a; 请求应答消息通常…

03 Temporal 详细介绍

前言 在后端开发中&#xff0c;大家是否有遇到如下类型的开发场景 需要处理较多的异步事件需要的外部服务可靠性较低需要记录保存某个对象的复杂状态 在以往的开发过程中&#xff0c;可能更多的直接使用数据库、定时任务、消息队列等作为基础&#xff0c;来解决上面的问题。然…

C语言学习第二十五天(顺序表)

顺序表 和数组的区别&#xff1a;首先顺序表的底层结构是数组&#xff0c;对数组的封装&#xff0c;实现了常用的增删改查等接口 分类&#xff1a; &#xff08;1&#xff09;静态顺序表 即使用定长数组存储元素 typedef int SLDataType; #define N 7 typedef struct SeqL…

RHCE 9版本考试资料

RHCE 9版本考试要求 01.安装和配置 Ansible 安装和配置 Ansible 按照下⽅所述&#xff0c;在控制节点 control上安装和配置 Ansible&#xff1a; 安装所需的软件包创建名为 /home/greg/ansible/inventory 的静态清单⽂件&#xff0c;以满⾜以下要求&#xff1a; node1 是 d…

2.6【渲染】混合渲染

一,混合渲染简介 当应用程序使用混合渲染选项时,应用程序必须确保渲染类型之间存在同步(例如,软件渲染、Khronos API渲染和blitting)。 以下示例演示了如何将软件渲染与Khronos渲染API混合使用。您需要按照以下步骤设置渲染目标和上下文: 创建渲染目标创建渲染上下文渲…

web项目理解

1.注解开发 这是一个 Java 自定义注解的定义&#xff0c;注解的名称是 AutoFill。以下是对代码的解释&#xff1a; java Target({ElementType.METHOD}) //注解在方法上面&#xff0c;指定注解的作用范围为方法 Retention(RetentionPolicy.RUNTIME) //指定注解的生命周期为运行…

【问题思考总结】只有load和store指令能够访存有什么好处?为什么能方便实现指令流水线?【CISC与RISC的区别】【2011 408真题T18 III】

问题 今天在搜寻这个问题的时候&#xff0c;发现鲜有人关注和回答&#xff0c;因此&#xff0c;在搜寻了一些外网的回答和资料后&#xff0c;通过思考&#xff0c;总结了一些个人的愚见&#xff0c;恳请各位指正。 思考 CISC与RISC的区别之我见 首先&#xff0c;这两种架构…

0级表空间后,又有0级全库备份,再1级表空间备份,xtts还认吗?

0级表空间后&#xff0c;又有0级全库备份&#xff0c;再1级表空间备份&#xff0c;xtts还认吗&#xff1f; 不认。此时需要根据提示报错的scn号再做备份再做恢复&#xff1a; backup incremental from SCN 1041682 tablespace DATA,USERS filesperset 300 format /bak/hisdb1…

C语言指针3

1.assert(条件); 一旦条件为假则报错 2.统一关闭assert方法: 在#include<assert.h> 上一行加上#define NDEBUG 3.但是引用assert会增加程序运行的时间 4.size_t等价于unsigned int 5.关于数组首元素的地址 两个特例: sizeof,&数组名 6. int main() {int a…

13.二进制枚举练习题

文章目录 二进制枚举练习题[78. 子集](https://leetcode.cn/problems/subsets/)[77. 组合](https://leetcode.cn/problems/combinations/)[1286. 字母组合迭代器](https://leetcode.cn/problems/iterator-for-combination/)[2397. 被列覆盖的最多行数](https://leetcode.cn/pro…

【算法Hot100系列】盛最多水的容器

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

ubuntu18使用docker编译和运行的步骤

在Ubuntu 18.04上使用Docker来编译和运行应用程序主要包括以下步骤&#xff1a; 安装Docker&#xff1a; 在Ubuntu上安装Docker之前&#xff0c;首先需要更新包索引并安装一些必要的包&#xff0c;以确保能够通过HTTPS使用仓库&#xff1a; sudo apt update sudo apt install a…

【设计模式-2.4】创建型——抽象工厂模式

说明&#xff1a;本文介绍设计模式中&#xff0c;创建型设计模式的抽象工厂设计模式&#xff1b; 工厂模式的问题 在【设计模式-2.2】创建型——简单工厂和工厂模式这篇博文中&#xff0c;介绍过飞机大战游戏里&#xff0c;使用简单工厂和工厂模式来创建坦克、飞机、Boss对象…

MySQL数据库,表的增量备份与恢复

1. 从物理与逻辑的角度 数据库备份可以分为物理备份和逻辑备份。物理备份是对数据库操作系统的物理文件&#xff08;如数据 文件&#xff0c;日志文件等&#xff09;的备份。这种类型的备份适用于在出现问题时需要快速恢复的大型重要数据库。 物理备份又可以分为冷备份&#xf…

【JAVA-Day65】Java内部类深度解析

Java内部类深度解析 《Java内部类深度解析》摘要引言一、理解内部类1. 内部类的基本概念和语法1.1 什么是内部类&#xff1f;1.2 内部类的语法结构1.3 内部类的基本概念 2. 不同类型的内部类详解2.1 成员内部类2.2 静态内部类2.3 局部内部类2.4 匿名内部类 二、内部类与普通类的…