ConcurrentHashMap和锁

news/2025/3/20 16:28:27/文章来源:https://www.cnblogs.com/exo123/p/18768379

为什么HashMap数组的长度是2的指数次幂?

因为HashMap的底层是数组+链表+红黑树,在插入元素时,需要通过索引获得插入元素的位置,计算索引的方法是使用哈希函数,将元素的哈希值与数组长度取模,当数组长度是2的指数次幂时,取模操作相当于对元素的哈希值进行二进制位与运算(假如数组长度是4,那么索引最大是3),可以更快的计算索引。

动态扩容时,原数组中的位置会移到什么位置?

每次扩容都是增加原来长度的倍数,原数组中的元素位置要么保持不动,要么等于旧数组时的索引位置再加上旧数组长度。

HsahMap在并发情况下为什么会造成死循环?

HashMap在并发执行put操作时发生扩容,如果一个线程被阻塞,另一个线程扩容结束后头插法会使得链表顺序与之前相反,而新数组在由阻塞的线程继续进行扩容操作时会变成旧数组,在并发执行后就可能会出现节点丢失,产生环形链表等情况;jdk1.8中改为尾插法,避免了产生环形链表,但避免不了节点丢失。

JDK1.7 HashMap扩容使用头插法

扩容后顺序会改变

 

jdk1.7 ConcurrentHashMap

 

 

 

 

 

java中的锁用来解决多线程并发情况下共享数据出现不一致的情况,对象头中存储锁标志位

无锁:没有对共享资源进行锁定(无竞争/乐观锁-CAS通过操作系统中一条指令来实现,能保证原子性)

偏向锁:先确定锁标志位,然后看mark word的前23bit记录着偏向的线程ID,如果当前有多个线程在争夺资源,则会变为轻量级锁

轻量级锁:线程在自己的虚拟机栈中开辟Lock Record的空间,线程通过CAS尝试获取锁,一旦获得将会使得对象头中Mark Word的前30个bit指向Lock Rocrd,Lock Record中存放mark word的副本,并指向该对象。其它线程将会自旋等待,如果自旋等待的线程超过1个,会变成重量级锁

重量级锁:需要通过Monitor对线程进行管控

sychrinized: 底层使用Monitor 监视器

 

无锁/乐观锁

CAS(compare and swap):new value代表想要将资源对象的状态值更新之后的值,old value表示之前获得的资源对象的值,若old value和当前资源对象的值不一样,则放弃swap操作,然后一直自旋(不断的重试CAS操作,配置循环次数防止死锁)

CAS的原子性由CPU指令集/底层指令架构支持。

 

vloatile关键字:保证数据的可见性,JVM将该变量从线程本地内存强行刷新到主内存中

        禁止指令重排,保证放在vloatile关键字之前的语句不会在后面执行,保证放在后面的语句不会提前执行。(多线程中发生指令重排,会影响结果)

AQS:同步框架

AQS成员变量

vloatile int state:使用int是因为资源有两种模式分别为独占模式和共享模式,当为共享模式时,可能会有多个线程在共享资源,所以state表示当前资源线程占用的数量,对其的修改使用CAS原子操作;

如果一个线程在当前没有获取到资源,那它可以进入队列进行排队,队列是先进先出的双向链表。

             Node head、 Node tail

Node成员变量

线程对象、节点在队列里的等待状态、前后指针等,等待状态有四个。

 

如何管理多线程同步状态?

两种使用场景:1、尝试获取锁,没有获取到立即返回 ——tryAquire() 调用该方法,成功获得锁时对想用资源进行操作,操作完释放,如果失败还想继续调用acquire()

        2、获取锁,愿意进行队列等待,直到获取 acquire() 

 

RenntrantLock,默认使用非公平锁

非公平锁:不按照锁的顺序分配,抢占式的,可能会有线程一直拿不到锁(在很多情况下,非公平锁的效率更高,当后请求的线程在前面休眠的线程恢复前拿到锁,提高并发性)

公平锁:锁的分配按照请求锁的顺序分配,比如说AQS的队列按照先进先出;如果当前线程已经获取锁,那么对state进行累加,可以继续使用锁,此外只有当前线程之前没有其他线程的情况下才会尝试获取锁,其它情况排队。

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

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

相关文章

麒麟系统V10系统安全加固

一、安装clamav杀毒软件 1.在clamav官网下载:https://www.clamav.net/downloads 也可以在github上下载早一点的版本:https://github.com/Cisco-Talos/clamav/releases 我这里安装clamav-1.1.2rpm -ivh clamav-1.1.2.linux.x86_64.rpm2.下载病毒库: https://database.clamav.…

孤独摇滚 K-ON wallpapers

双厨狂喜 孤独摇滚K-ON

医疗器械行业IPD流程设计:6个关键问题与解决方案

在当今竞争激烈的医疗器械行业,产品的创新与快速上市能力是企业生存和发展的关键。IPD(集成产品开发)流程作为一种先进的产品开发管理模式,正逐渐成为医疗器械企业提升竞争力的重要手段。然而,在实际应用中,许多企业在 IPD 流程设计方面面临着诸多挑战。本文将深入探讨医…

KUKA库卡KR360_R2830机械臂维修减速机卡住了

库卡机器人维修减速机卡死,作为一种常见的机械故障,其成因往往复杂多样,通常可以归结为长时间的高强度工作、外部异物的侵入、安装过程中的疏忽以及润滑系统的失效等多种因素。以下是对这一故障常见原因的详尽阐述,以及一些实用的维修建议:库卡机器人减速机卡死现象的根源…

【原厂】点阵LED数码管驱动/内置显示RAM为8x16位-LED显示驱动芯片VK1640 SOP28

产品品牌:永嘉微电/VINKA 产品型号:VK1640 封装形式:SOP28 概述 VK1640是一种数码管或点阵LED驱动控制专用芯片,内部集成有数据锁存器、LED 驱 动等电路。SEG脚接LED阳极,GRID脚接LED阴极,可支持8SEGx16GRID的点阵LED显示。 适用于小型LED显示屏驱动。采用SOP28的封装形式…

portainer学习笔记1

Portainer是一款非常好用的docker容器管理平台,部署也很easy。# 创建portainer数据卷 docker volume create portainer_data # 拉取镜像启动portainer docker run -d -p 8000:8000 -p 9443:9443 \ --name portainer --restart=always \ -v /var/run/docker.sock:/var/run/dock…

安装Python保姆级教程(Pycharm破解码+解释器安装)

一、进入Python官网首页,下载最新的Python版本 https://www.python.org/downloads/ 选择最新的Python3.10.5,下载64位的版本 二、下载完成后,进行安装 1.双击Python-3.10.5-amd64.exe 3.出现此页面表示安装成功 三、运行Python 1.Win+R打开控制台,输入Python 此时出现了一…

dify知识库

一、概述 知识库功能将 RAG 管线上的各环节可视化,提供了一套简单易用的用户界面来方便应用构建者管理个人或者团队的知识库,并能够快速集成至 AI 应用中。 开发者可以将企业内部文档、FAQ、规范信息等内容上传至知识库进行结构化处理,供后续 LLM 查询。 相比于 AI 大模型内…

DevOps 平台选型对比:功能与价值剖析

在数字化转型加速的当下,高效的软件开发流程成为企业竞争力的关键。DevOps 平台作为整合开发与运维的重要工具,其选型至关重要。Gitee DevOps 是一款在行业内表现出色的平台,能为企业提供从代码管理到部署上线的全流程支持。通过对其功能、价格、用户体验等多方面与市场竞品…

关于如何搭建anythingllm+ollama(deepseekr1、嵌入模型)+milvus的本地知识库语言模型

这里只是对于自己在部署过程中踩到的坑做个记录。 以anythingllm为平台,接入基于ollama运行deepseekr1通用模型、嵌入模型,使用milvus作为向量数据库。其中milvus和anythingllm均在docker desktop中运行。 一、ollama 1.首先在ollama官网下载并安装ollama。 2.然后在官网的mo…

Endnote 修改了参考文献格式后,文献的引用有的上标,有的不是上标

如上图,有的文献引用是正常格式,有的文献引用的的方括号是上标的形式。解决如下: 打开Endnote,找到“编辑”---“输出样式”---“编辑XXXXXX”(XXXXXX表示你正在使用的参考文献格式)---“引用”---“模板”---“Citatian” 将方框中的“Bibliography Number”两边的方括号…

Explain查询Sql效率

Explain分析Sql性能 前言 在我们平时开发中,因为系统可能属于初级阶段,数据库的数据还不是很多,所以自我感觉写的Sql语句上运行起来速度还不错,殊不知,随着时间推移,数据量日益增多,系统的查询效率会在打折扣,所以,Sql性能调优手段还得了解一下下。 Explain是什么?有…