JUC-JMM模型、CAS、AQS

news2025/1/9 15:10:20

JMM(Java内存模型),主要描述了一组规则,主要定义了程序执行过程中变量的访问方式来保证单线程、多线程下的正常执行。JVM运行的实体是线程,每个线程运行时,都会创建一个工作内存【栈空间(栈帧)】来保存所有的私有变量。

JMM内存模型规定所有遍历都存储在主内存中,主内存的变量所有线程都可以共享,对主内存中的变量进行操作时,不同线程要copy主内存的内容,然后在自己的工作内存中进行,完成后刷回主内存,所有线程通过主内存来通信。

 JMM围绕着原子性、有序性、可见性三点展开

主内存:所有线程创建的实例对象都放在主内存,不管该实例对象是成员变量,还是局部变量,类信息、常量、静态变量都是放在主内存中,属于所有线程共享区域,所以存在线程之间安全问题

工作内存:主要存储方法内部的变量和主内存中变量的副本,每个线程只操作工作内存中的数据,对其他线程不可见,线程安全。

JMM数据同步的原子操作  8个:(保证多线程安全)

lock-unlock、read-load、use-assign、store-write

JMM如何解决原子性、可见性、有序性问题

原子性:通过synchronized和Lock实现原子性

可见性:volatile关键字保证了可见性,变量被volatile关键字修饰后没回保证此变量修改的值立即刷新到主内存,被其他线程可见。synchronized和Lock同一时刻只有一个线程能访问同步代码块,所以是也支持了可见性。

有序性:volatile保证了有序性、synchronized和Lock也保证了有序性

happens-before原则:

只通过volatile和synchronized来保证原子性、可见性、有序性,并发程序会比较麻烦。所以jdk1.5以后提供了happens-before原则:

1、程序顺序原则:一个线程内,程序顺序执行

2、锁规则:unlock操作必须发生在下一个加锁之前,也就是lock和unlock一一对应。

3、volatile规则:volatile变量被线程访问时,强迫从主内存读取最新变量值,发生变化时会强迫刷新到主内存,任何时候,不同线程总能看到改变量最新值。

4、线程启动规则:start()方法先于每个动作

5、传递性:A优先于B,B优先于C,A优先于C

6、线程终止规则:线程所有操作优先于线程终结。

volatile关键字可以保证可见性和有序性

volatile关键字是Java虚拟机提供的轻量级的同步机制,保证了Java内存模型的两个特性,可见性、有序性。

可见性:对非volatile修饰的变量,不同的线程从主内存拷贝到CPU缓存中,多线程的情况下就会拷贝到多个不同的CPU的cache中,volatile修饰的变量会强制每次去主内存拷贝,并且发生改变后立即刷新回主内存。

有序性:volatile关键字会禁止指令重排。

问题:volatile保证不了原子性,可以使用原子类【java.util.concurrent.atomic解决原子性问题

原子类的实现主要利用CAS(compare and swap)+ volatile 和本地方法实现

CAS:(compare and swap比较并交换)

CAS指令有3个操作数,内存值V,旧的预期值A,要修改的更新值B,当且仅当A==B会执行,其他情况自旋重新执行。【CAS同样需要volatile来保证可见性】

cas是一种系统原语,执行过程不允许中断,保证了原子性,具体是通过Unsafe类的本地方法实现

执行过程:【方法:获取变量+1操作】

1线程A获取变量值为3之后未执行+1时,被挂起,此时期望更改后的值为4;

2线程B获取变量值为3之后执行+1并修改,由于变量被volatile修饰,所以立即刷回主内存;

3线程A执行,执行compareAndSwapInt(),发现内存获取的值和之前的值不同,则修改失败,只能重新获取

4线程A重新获取变量进行+1

CAS的缺点:

(1)在线程执行不成功的情况下会一直循环等待重新执行,长时间不成功,消耗太大

(2)只能保证一个共享变量的原子操作,多变量操作时无法保证

(3)会导致ABA问题

由于CAS不能保证多变量操作的原子性,所以通过锁来保证原子性

AQS(AbstractQueuedSynchronizer 抽象队列同步器):

AQS的核心思想是,如果被请求的共享资源是空闲的,则设置当前请求此资源的线程为有效的工作线程,并将共享资源上锁。但如果被请求的资源被占用,那么久需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是用CLH队列锁实现的。

【CLH队列时虚拟的双向队列,AQS将等待的线程封装成一个CLH队列的Node节点实现锁的分配,通过CAS、自旋、LockSupportpark的方式,维护state变量状态,使并发达到同步效果】

锁和同步器的关系:锁,面向使用者,调用即可、同步器,面向锁的实现者

AQS对资源的共享方式有两种:

  • 独占:只有一个线程执行,如ReentrantLock,可以分为公平锁和非公平锁 
    • 公平锁:按照线程在队列中的排队顺序
    • 非公平锁:当线程要获取锁时,无视队列顺序,直接抢
  • 共享:多个线程可同时执行,如Semaphore/CountDownLatch

AQS底层使用模板方法模式:

模板方法模式的使用,自定义一个同步器只需要重写如下方法,其他方法均为final。

isHeldExclusively()//该线程是否正在独占资源,用的condition需要实现

//独占
tryAcquire(int)//独占方式,尝试获取资源
tryRelease(int)//独占方式,尝试释放资源

//共享
tryAcquireShared(int)//共享方式,尝试获取资源
tryReleaseShared(int)//共享方式,尝试释放资源

ReentrantLock为例,state初始化为0,A线程lock()时,调用tryAcquire()独占资源并将state+1,此后其他线程就会请求失败,直到A线程unlock()到state=0。在释放锁之前,A线城内部可以重复获取此锁(state累加),也就是可重入,但是获取的次数等于释放的次数,state为0才可以释放锁。

CountDownLatch为例,任务有N个子线程执行,State初始化为N,每个线程执行完之后countDown一次,state-1,这时要用CAS执行,所有线程执行完,state变为0。

AQS中独占锁和共享锁的操作流程:

独占锁是持有锁的线程释放之后才会唤醒下一个

共享锁是线程获取锁之后就会唤醒下一个线程,所以共享锁在获取锁和释放锁时都会调用doReleaseShared方法唤醒下一个线程,这个过程会受共享线程数量的限制。

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

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

相关文章

接口测试的测试要点

接口测试的测试要点,你知道都有哪些吗? 接口测试是软件测试中的重要组成部分,它的目的是评估接口的质量和可靠性,以保证系统的正常运行。在进行接口测试时,必须要考虑到以下几个方面: 测试用例的编写 测试…

安科瑞电力监控系统在虹科创新改造项目的应用

摘要:随着电力系统正向着高可靠性、高自动化、高信息化水平方向迅猛发展,对电网的监控已成为国内外高度重视的关键问题,特别是监控系统在电力系统中起着控制和监测等重要作用。本文针对开闭所供配电系统特点及供配电系统高可靠性的要求&#…

基于springboot+vue+elementui的健身房会员管理系统的

为了帮助用户更好的了解和理解程序的开发流程与相关内容,本文将通过六个章节进行内容阐述。 第一章:描述了程序的开发背景,程序运用于现实生活的目的与意义,以及程序文档的结构安排信息; 第二章:描述了程序…

可以在商场内部使用的导航地图?商场导览图怎么画?

可以在商场内部使用的导航地图?随着商业的发展,商场和商业综合体的规模越来越大,在注重消费者购物体验的时代,消费者想方便地找到心仪的品牌或美食,商场内具有“导示”作用的标志很重要。导示系统具有引导、说明、指示…

1. Ansible介绍,什么是Ansible?Ansible能用来做什么?

什么是Ansible?Ansible能用来做什么? 如果您是系统工程师或IT管理员,或者只是在IT部门工作的任何人,您可能会在环境中执行大量重复性任务, 无论是每天调整大小和创建新主机或虚拟机、 在其上应用配置、 修补数百台服务器&#xff6…

Nginx基础概念

一.nginx简介 1.什么是nginx? Nginx 是高性能的 HTTP 和反向代理的web服务器,处理高并发能力是十分强大的,能经受高负 载的考验,有报告表明能支持高达 50,000 个并发连接数。 其特点是占有内存少,并发能力强,事实上n…

「实在RPA·烟草数字员工」助力烟草行业数字化转型加速度

烟草行业作为烟草产业链上重要一环,外部连接烟草工业企业、零售客户、消费者,内部包含营销、专卖、烟叶、物流等诸多业务,信息系统众多,企业数据量庞大。因此,清楚地了解自身存在的痛点,找到适合自身业务需…

Vmware虚拟机多开技巧

多年前,由于工作关系,在台式机上使用VMware虚拟多个操作系统进行微软AD实验。那时候电脑内存大概是4--8Gb,开3个也毫无压力。后来我的笔记本都16Gb内存了运行3个虚拟机竟然因为内存不足报错。 然后经过分析和查找,找到原因了。这里…

VR全景虚拟史记馆互动体验生动还原了历史画面

历史展览馆线上VR全景展示是一种新型的历史文化展示方式,它通过VR虚拟现实技术将历史事件、文化背景等内容呈现给观众。相比传统的实体历史展览馆,线上VR全景展示具有以下几个方面的突破: 实现更大范围、更多样化的内容展示 由于传统的历史展…

拉货搬家货运APP开发分析和功能列表

作为国家经济发展的重要基础设施,物流行业正在面对转型升级的风口。巨大的市场体量,也迎来了激烈的市场竞争。为了从同质化的服务中脱颖而出,开拓更大的市场,并且解决线下司机的载货痛点,货运APP的开发必不可少。 开发…

GO语言并发编程入门:Goroutine、Channel、Context、并发安全、GMP调度模型

GO语言并发编程入门:Goroutine、Channel、Context、并发安全、GMP调度模型 1.GO并发介绍 并发:多线程程序在一个核的cpu上运行。 并行:多线程程序在多个核的cpu上运行。 由上可知并发不是并行,并行是直接利用多核实现多线程的运…

C语言_数据类型[详细分析]

接上一篇:C语言_关键字_标识符简介 本次来分享C语言的数据类型,是博主的一些学习笔记的和心得的总结,话不多说,开始上菜: 此博主在CSDN发布的文章目录:我的CSDN目录,作为博主在CSDN上发布的文章…

如何零基础快速搭建一个后台管理系统

真在的大师,都永远怀着一颗学徒的心!!! 大家好,我是为你们操碎了心的小编,今天我又带来了一款轻量级的saas后台管理框架,让你零基础也可快速搭建一个功能强大的后台管理系统。 niucloud-admin采…

什么是AOP,如何实现?(有落地代码)

AOP 的核心思想是将横切关注点抽象为一个独立的模块(称之为“切面”),然后在需要应用它的地方进行调用。比如,在需要记录日志的方法中,我们可以定义一个切面来负责日志记录,这样所有调用该方法的地方都会被…

hugging face开源的transformers模型可快速搭建图片分类任务

2017年,谷歌团队在论文「Attention Is All You Need」提出了创新模型,其应用于NLP领域架构Transformer模型。从模型发布至今,transformer模型风靡微软、谷歌、Meta等大型科技公司。且目前有模型大一统的趋势,现在transformer 模型不仅风靡整个NLP领域,且随着VIT SWIN等变体…

关于I/O

I/O 1. 概念1.1 页缓存的简单工作流程1.2 页缓存的写机制或者写触发的时机1.3 为什么需要套字节缓冲区1.4 套接字缓冲区的简单流程 2. 传统I/O方式2.1 传统I/O读写流程2.2 传统 I/O的性能问题 3. DMA技术3.1 将数据写入磁盘的流程3.2 从磁盘读取数据的流程 4. 网络数据传输流程…

【python】制作一个点单小程序!

周末总是在吃的方面,及其纠结,今天来制作一个点单小程序,加入自己喜欢吃的东西,来慢慢挑选,让每个周末快乐无限! 一.安装环境 python 3.7.8 QT xlrd、xlwt库使用pip接口进行安装 pip install xlrd pip …

DMBOK知识梳理for CDGA/CDGP——第一章数据管理

关 注gzh“大数据食铁兽“,回复“知识点”获取《DMBOK知识梳理for CDGA/CDGP》常考知识点(第一章数据管理) 第一章 数据管理 第一章在 CDGA|CDGP考试中分值占比均不是很高,主要侧重点是考概念性的知识,理解数据管理的…

设计模式 -第1部分 避免浪费- 第1章 Flyweight 模式 - 共享对象避免浪费

第1部分 避免浪费 注:其内容主要来自于【日】-结城浩 著《图解设计模式》20章节 极力推荐大家阅读原著 第1章 Flyweight 模式 - 共享对象避免浪费 1.1 Flyweight 模式 Flyweight 的意思"轻量级",其在英文中的原意指比赛中选手体重最轻等级的一…

迪赛智慧数——饼图柱状图(基本饼图和基本柱状图):“怒路症”数据解读

效果图 35%的司机承认自己属于“路怒族”,还有65%的人表示自己不是“路怒族”。 近日,上海两车高架上斗气碰撞差点掉落高架,上海高架出现“史诗级”斗气车。小编在此呼吁大家,开车路上减压,避免坏情绪伴随&#xff0c…