【多线程】Java中是如何保证多线程间的数据共享的?

news2024/12/23 15:05:39

文章目录

  • 前言
  • 一、Java的内存模型
  • 二、保证可见性的方式
    • volatile
    • synchronized
    • lock
    • final
  • 三、volatile的底层实现
  • 总结

前言

在讨论这个问题之前,我们可以先瞅瞅Java的内存模型JMM,JMM可不要和JVM混为一谈。我们说的是内存模型JMM(Java Memory Model)

一、Java的内存模型

在这里插入图片描述

稍微解释一下CPU的缓存,这里CPU的缓存有三级,L1,L2和L3。

  • L1是访问速度最快的,是线程独享。
  • L2次之,属于内核独享。
  • L3是最慢的,是多核共享。

当CPU执行指令需要数据的时候,会先在L1,L2,L3中依次寻找,若是找不到,则会去JVM中寻找,而JMM则在CPU和主内存之间来保证我们需要的可见性和有序性。

这个JMM就是Java内存模型的核心,可见性有序性都是在这里实现。
而主内存就是JVM,就是我们的堆内存。

二、保证可见性的方式

可见性是指,当多个线程操作同一个数据的时候,保证一个线程的修改对其他线程是可见的,也就是说不管多个线程如何操作,如何并发,他们在同一时间取到的值是相同的。

为了保证可见性,我们一般有以下几种方案:、

volatile

可以用volatile来修饰基本数据类型,可以保证每次CPU操作数据的时候,都直接操作的是主内存的值。

synchronized

对于synchronized来说,是谁拿到锁,谁执行操作,对于拿到锁的线程来说,前边线程的操作是可见的。

lock

lock是基于CAS和volatile的修改操作,可以保证操作数据时前边操作的可见性。

final

final修饰的是常量啊,没法写,只读,当然是全局可见的

这里有一个小点:
我们清楚,volatile修饰基本数据类型的时候是可以保证可见性的,但是若是修饰的是引用数据类型呢?
一般没人这么搞,甚至平时工作中volatile都很少使用,一不留神系统的性能会降低几个维度。但是面试中常被问到,我们可以这样回答:若volatile修饰的是引用数据类型,则只能保证引用数据类型的地址是可见的,里边的值不可见。就这。

三、volatile的底层实现

稍微看看volatile的底层实现吧,其实

volatile的底层是汇编的lock指令,这个指令会强行要求将值写入主内存,并且忽略Store
Buffer这种缓存,从而达到可见性的目的,同时利用MESI协议,让其他缓存行失效。

我们晓得将java文件编译为class文件的时候,会基于JIT做优化,调整指令的顺序,从而提升执行效率,这个过程叫指令重排。

在CPU层面也会调整指令的顺序来提升性能。而这个指令重排会导致一些问题,我们看看volatile是如何解决这个问题的。

被volatile修饰的属性,在编译时会在先后增加内存屏障。这里的提到的内存屏障一般有四种

  • SS: StoreStore屏障前的读写操作必须全部完成,才会继续屏障之后的操作
  • SL: StoreLoad屏障前的写操作必须全部完成,才会继续屏障之后的读操作
  • LL: LoadLoad屏障前的读操作必须全部完成,才能继续屏障之后的读操作
  • LS: LoadStore屏障前的读操作必须全部完成,才能继续屏障之后的写操作

这里volatile的原理就如下
在这里插入图片描述

  • 可以看到对于volatile的写操作
    之前添加了StoreStore内存屏障,必须完成之前的读写操作才能继续volatile的写操作。
    而后添加了StoreLoad屏障,要求其前边的volatile写操作完成,才能继续之后的读操作。

这样就保证了在对volatile修饰的值执行写操作的时候,之前的读写操作已经全部完成,而其后的读操作在等待写操作完成再去读值。

  • 而对于volatile的读操作,在其后添加了一个LoadLoad屏障和LoadStore屏障,这里这个LoadLoad屏障不是很理解,查阅了诸多资料也没有眉目,若是有小伙伴知晓的,烦请不吝赐教。
    而LoadStore屏障则保证了volatile的读操作全部完成之后,再继续之后的写操作。

这样volatile的读操作完成之后,才会执行其他的写操作。保证了读到的值是确定的不变的。

总结

Java的线程间共享值的处理方式就大致讲解完毕了,若有不懂的地方,尽情留言,我们一起讨论,学习,感谢。

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

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

相关文章

JavaSE-06 [面向对象OOP + 封装]

JavaSE-06 [面向对象OOP 封装] 第一章 面向对象思想 1.1 面向过程和面向对象 面向过程: 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了面向对象: 面向对象是…

博弈论(NIM游戏——取石子)相关的题目

1.异或的性质 🏳️‍🌈🏳️‍🌈🏳️‍🌈🏳️‍🌈🏳️‍🌈🏳️‍🌈 2.nim游戏 (基础) 891. Nim游戏 - AcWin…

直播软件app开发:如何处理直播延迟问题?

随着直播技术的发展,直播软件app的开发变得越来越普遍。然而,直播延迟问题一直是直播软件app开发中的一个挑战。在本文中,我们将探讨如何解决直播延迟问题,提高用户体验。 直播延迟的原因 直播延迟的原因是多方面的。其中最主要…

【Mycat2】介绍、安装、部署、配置、测试与 Bugs

文章目录 一、MyCat 概览1.1 简介1.2 官网网址1.3 仓库地址1.4 Mycat1.x 与 Mycat2 功能对比1.5 下载1.5.1 先决条件1.5.2 Mycat2 安装包(以下二选一) 1.6 Mycat2权威指南1.7 原型库什么是兼容性 SQL?什么是 Prototype 服务器?原型…

shell第二次作业

一、编写脚本for1.sh使用for循环创建20账户,账户名前缀由用户从键盘输入,账户初始密码由用户输入。 1、创建脚本for1.sh [rootlocalhost ~]# vim for1.sh2、编辑脚本内容 3.运行 [rootlocalhost ~]# bash for1.sh 请用户输入账户名的前缀&#xff1a…

WPS AI 再次引爆办公软件行业,以后写文档可由AI代笔

国内外办公软件两大巨头聚齐,使用AI助力再次成标配。 2023年3月16日,微软发布了 Microsoft 365 Copilot,Microsoft 365 这个名字听起来比较陌生,它集成了Office 365 企业版、Windows 10 企业版以及企业移动性安全性,以…

基于Jira的持续交付流水线实践方式

点击上方蓝字⭐️关注“DevOps云学堂”,接收最新技术实践 今天是「DevOps云学堂」与你共同进步的第 19 天 DevOps 为什么很重要? 软件和 Internet 改变了我们身处的世界,同时也改变了购物、娱乐、银行等行业的运营方式。软件不再仅仅是为业务…

【unity项目实战】3DRPG游戏开发03—— 绘制low poly风格的场景

搭建场景 拖入一颗树,按住V键,表示顶点吸附,点击树的底部,他就会自动吸附到相邻的平面上了 如果你的摄像机位置不是很好,我们可以场景移动到合适的位置,可以点击摄像机,按下键盘ctrl+shift+F同步调整摄像机位置 绘制low poly风格的环境 安装Ploybrush插件,并导入样…

linux安装南大通用数据库 GBase 8s V8.8

linux安装南大通用数据库 GBase 8s V8.8 1、操作系统、数据库2、下载链接3、安装文档4、安装前准备4.1、以root用户创建 gbasedbt 组和用户4.2、创建 GBase 8s 数据库安装目录4.3、上传并解压安装包 5、安装5.1、执行安装程序5.2、回车继续 直到接受许可条款5.3、输入安装目录绝…

Windows安装使用Redis,redis基本使用教程,python连接调用redis

文章目录 下载:安装:redis安装成Windows服务:修改密码:客户端连接:基本使用:python里调用redis: 下载: https://github.com/microsoftarchive/redis/releases/tag/win-3.2.100 安装…

机器学习:基于多项式贝叶斯对蘑菇毒性分类预测分析

基于多项式贝叶斯对蘑菇毒性分类预测分析 作者:i阿极 作者简介:Python领域新星作者、多项比赛获奖者:博主个人首页 😊😊😊如果觉得文章不错或能帮助到你学习,可以点赞👍收藏&#x1…

银行数字化转型导师坚鹏:银行业务数字化创新工作坊

银行业务数字化创新工作坊 课程背景: 很多银行存在以下问题: 不清楚如何进行业务数字化创新? 不知道如何开展银行数字化营销工作? 不知道零售业务数字化创新成功案例? 学员收获: 学习原创银行BLM…

【音视频】国际双向对讲方案

语音对讲的的整体流程为: 先拉流播放设备的视频;使用WebRTC推送语音流到ZLM服务;使用SIP协议下发Broadcast指令给设备;接收到设备的OK指令后,请求ZLM的startSendRtp接口,TCP协议请求startSendRtpPassive接口…

springboot集成webmagic和selenium,并部署到linux(问题坑)

springboot集成webmagic和selenium,并部署到linux(问题坑) 首先参考两个源代码spring boot集成找不到org.openqa.selenium.remote.AbstractDriverOptions的类文件代理ip--更换一个网页同时更换一个代理ip代理ip网址部署linux谷歌浏览器下载谷…

Python冒泡排序的实现

时间复杂度: 最坏时间复杂度O(n^2) 最优时间复杂度O(n):表遍历一次发现没有任何可以交换的元素,排序结束,这是最理想的 稳定性:稳定,(执行前后没有对数据没有变化,位置等) 原理和方…

供需两端催化口腔医疗服务市场增长 未来将呈现线上化、智能化、品质化三大趋势

一、口腔医疗服务行业概述 口腔由唇、颊、舌、腭、涎腺、牙和颌骨等部分组成。口腔疾病种类繁多,伴随人全生命周期,常见疾病有龋病、牙周疾病、牙髓病、根尖周病、牙齿缺损、错颌畸形等,多数口腔疾病的发病率高,诊疗需求大。除此…

深度强化学习——策略学习(3)

本文的重点:使用一个神经网络来近似策略函数Π 我们使用一个神经网络来近似策略函数,这个神经网络叫做策略网络,他可以用来控制agent运动,想要训练这个神经网络,就要用到policy gradient算法 策略函数Π的输入是当前…

苹果离开中国制造影响有多大?后果不堪设想,可能是灭顶之灾

由于苹果力推印度制造,各方都对苹果与中国制造的关系高度关注,那么苹果真的离开中国制造的话,结果会如何呢?对双方来说,影响会非常大,超出想象。 一、中国制造对苹果的依赖 苹果对产业链拥有巨大的影响力&a…

Python基础快速入门

一、中文编码问题 带大家过一遍菜鸟学python的基础内容 二、Python基础语法 1、Python 中的标识符是区分大小写的。 以下划线开头的标识符是有特殊意义的。以单下划线开头 _foo 的代表不能直接访问的类属性,需通过类提供的接口进行访问,不能用 from x…

用Socket API建立简易TCP服务端、客户端

//---------------------- //-- 用Socket API建立简易TCP客户端 // 1 建立一个Socket // 2 连接服务器 connect // 3 接收服务器信息 recv // 4关闭套接字 closesocket // -- 用Socket API建立简易TCP服务端 // 1 建立一个socket // 2 bind 绑…