violate关键字---java高并发

2023-11-17

内存模型相关概念

计算机在执行程序时,每条指令都是在CPU中执行的,而执行指令过程中,势必涉及到数据的读取和写入。由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这时就存在一个问题,由于CPU执行速度很快,而从内存读取数据和向内存写入数据的过程跟CPU执行指令的速度比起来要慢的多,因此如果任何时候对数据的操作都要通过和内存的交互来进行,会大大降低指令执行的速度。因此在CPU里面就有了高速缓存

也就是,当程序在运行过程中,会将运算需要的数据从主存复制一份到CPU的高速缓存当中,那么CPU进行计算时就可以直接从它的高速缓存读取数据和向其中写入数据,当运算结束之后,再将高速缓存中的数据刷新到主存当中。举个简单的例子,比如下面的这段代码:

i = i + 1;
  • 1
  • 单线程:当线程执行这个语句时,会先从主存当中读取i的值,然后复制一份到高速缓存当中,然后CPU执行指令对i进行加1操作,然后将数据写入高速缓存,最后将高速缓存中i最新的值刷新到主存当中。并没有什么问题。

  • 多线程:在多核CPU中,每条线程可能运行于不同的CPU中,因此每个线程运行时有自己的高速缓存(对单核CPU来说,其实也会出现这种问题,只不过是以线程调度的形式来分别执行的)。本文我们以多核CPU为例。++比如同时有2个线程执行这段代码,假如初始时i的值为0,那么我们希望两个线程执行完之后i的值变为2。但是事实会是这样吗?++
    可能存在下面一种情况:

初始时,两个线程分别读取i的值存入各自所在的CPU的高速缓存当中,然后线程1进行加1操作,然后把i的最新值1写入到内存。此时线程2的高速缓存当中i的值还是0,进行加1操作之后,i的值为1,然后线程2把i的值写入内存。最终结果i的值是1,而不是2。

这就是著名的缓存一致性问题。通常称这种被多个线程访问的变量为共享变量

  也就是说,如果一个变量在多个CPU中都存在缓存(一般在多线程编程时才会出现),那么就可能存在缓存不一致的问题。

  为了解决缓存不一致性问题,通常来说有以下2种解决方法:

  1. 通过在总线加LOCK锁的方式
  2. 通过缓存一致性协议

这2种方式都是硬件层面上提供的方式。

在早期的CPU当中,是通过在总线上加LOCK#锁的形式来解决缓存不一致的问题。因为CPU和其他部件进行通信都是通过总线来进行的,如果对总线加LOCK#锁的话,也就是说阻塞了其他CPU对其他部件访问(如内存),从而使得只能有一个CPU能使用这个变量的内存。比如上面例子中 如果一个线程在执行 i = i +1,如果在执行这段代码的过程中,在总线上发出了LCOK锁的信号,那么只有等待这段代码完全执行完毕之后,其他CPU才能从变量i所在的内存读取变量,然后进行相应的操作。这样就解决了缓存不一致的问题。

但是上面的方式会有一个问题,由于在锁住总线期间,其他CPU无法访问内存,导致效率低下。

所以就出现了缓存一致性协议。最出名的就是Intel 的MESI协议,MESI协议保证了每个缓存中使用的共享变量的副本是一致的。它核心的思想是:当CPU写数据时,如果发现操作的变量是共享变量,即在其他CPU中也存在该变量的副本,会发出信号通知其他CPU将该变量的缓存行置为++无效状态++,因此当其他CPU需要读取这个变量时,发现自己缓存中缓存该变量的缓存行是无效的,那么它就会从内存重新读取。

这里写图片描述

violate关键字(2.3)

易变得、不稳定的。

当使用violate去申明一个变量时,就等于告诉了虚拟机这个变量极有可能会被某些程序或者线程修改。为了确保这个变量被修改后,应用程序中的其他的线程都可以看到这个改动,虚拟机就必须采用一些特殊的手段,保证这个变量的可见性等特点。

violate缺点

violate无法保证一些符合操作的原子性,用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最的值。volatile很容易被误用,用来进行原子性操作。

violate

Java运行时有个一个内存区域是jvm虚拟机栈,每一个线程运行时都有一个线程栈,线程栈保存了线程运行时候变量值信息。当线程访问某一个对象时候值的时候,首先通过对象的引用找到对应在堆内存的变量的值,然后把堆内存变量的具体值load到线程本地内存中,建立一个变量副本,之后线程就不再和对象在堆内存变量值有任何关系,而是直接修改副本变量的值,在修改完之后的某一个时刻(线程退出之前),自动把线程变量副本的值回写到对象在堆中变量。这样在堆中的对象的值就产生变化了。下面一幅图描述这写交互:

这里写图片描述

  • read and load 从主存复制变量到当前工作内存
  • use and assign 执行代码,改变共享变量值
  • store and write 用工作内存数据刷新主存相关内容

其中use and assign 可以多次出现,但是这些操作并不是原子性的,也就是在read load之后,如果主内存count变量发生修改之后,线程工作内存中的值由于已经加载,不会产生对应的变化,所以计算出来的结果会和预期不一样。对于volatile修饰的变量,jvm虚拟机只是保证从主内存加载到线程工作内存的值是最新的。

例如假如线程1,线程2 在进行read,load 操作中,发现主内存中count的值都是5,那么都会加载这个最新的值在线程1堆count进行修改之后,会write到主内存中,主内存中的count变量就会变为6,线程2由于已经进行read,load操作,在进行运算之后,也会更新主内存count的变量值为6。导致两个线程及时用volatile关键字修改之后,还是会存在并发的情况。

使用

用一个线程来控制开关变量,通知其他线程的开关闭合情况。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

violate关键字---java高并发 的相关文章

  • Java基础语法知识

    一 Java基础知识 Java程序可分为结构定义语句和功能执行语句 结构定义语句 用来声明一个类或方法 功能执行语句 用来实现具体的功能 package homework java程序中最基本的组成单位是类 类的定义格式 public cl
  • 集合框架 — ConcurrentHashMap

    集合框架 ConcurrentHashMap 一 ConcurrentHashMap JDK1 7 1 实现结构 2 保证并发安全 分段锁技术 3 put 和 get 方法 二 ConcurrentHashMap JDK1 8 1 实现结构
  • substring的常用两个方法

    概述 1 substring是用来截取字符串的 根据参数的个数不同 方法含义也不同 2 substring 0 2 这个只含开头不含结尾 因此截取是截取两个字符 从第一个到第二个字符 不包含第三个 3 substring 2 这个表示截掉前
  • Java中map的分类和常见的情况

    Java为数据结构中定义了一个接口Java util Map 它有四个实现类 分别是HashMap Hash table LinkedHashMap 和 TreeMap Map主要用于存储键值对 根据键得到值 因此不允许键重复 重复了覆盖了
  • 什么是“堆”,"栈","堆栈","队列",它们的区别?

    一 堆 什么是堆 又该怎么理解呢 堆通常是一个可以被看做一棵树的数组对象 堆总是满足下列性质 堆中某个节点的值总是不大于或不小于其父节点的值 堆总是一棵完全二叉树 将根节点最大的堆叫做最大堆或大根堆 根节点最小的堆叫做最小堆或小根堆 常见的
  • Random类和UUID以及验证码的生成

    一 介绍与测试 Random 产生随机数 UUID 通用唯一识别码 目的是让分布式系统中的所有元素 都能有唯一的辨识信息 根据当前时间和电脑网卡 生成一段字符 Radom类 import java util public class Ran
  • 计算阶乘的两种实现方式(Java)

    本文以计算5的阶乘为例 5 5 4 3 2 1 120 一 循环阶乘 1 While循环 public class TestWhileFactorial public static void main String args int res
  • JAVA中常用的Queue的介绍

    目录 1 java中队列的分类以及队列的介绍 2 PriorityQueue队列的介绍 2 1 PriorityQueue继承结构和方法解读 2 2 PriorityQueue的构造器的实现 3 Deque 双向队列 的简单介绍 3 1 A
  • Stream使用技巧(1)------数据处理技巧

    Stream使用技巧 1 数据处理技巧 一 背景 作为java8新特性之一的Stream API为开发者带来了极大的便利 它可以对我们需要操作的集合进行非常复杂的操作 以活的我们想要的结果 本文不会告诉你什么是Stream 毕竟网上花里胡哨
  • ⛳ Class.forName()方法

    目录 Class forName 方法 特点 举例 Class forName 方法 Class forName 是Java中的一个反射方法 用于根据类的完整限定名 fully qualified name 加载类并返回对应的Class对象
  • 【Windows系统5分钟搭建Linux环境】

    安装 Linux 虚拟机 第1步 下载 VirtualBox 第2步 下载 Vagrant 第3步 拉取Linux虚拟机镜像 第4步 网络配置 网络地址转换 端口转发 注意 电脑需要开启 CPU 虚拟化 电脑开机时 进入BIOS界面设置 第
  • JAVA-程序的编译过程及运行过程

    目录 前言 一 Java程序的执行过程 1 编译期 2 运行期 二 小例子 1 进入cmd窗口 2 编译期 3 运行期 总结 前言 在之前我们做了第一个案例 Hello World 案例 也对其进行了详细的解析 HelloWorld案例 详
  • 视频流截取保存到本地路径(打包jar包CMD运行)

    需求 现在有一批https的监控视频流URL 需要以多线程模式监听视频流 对视频流进行每三秒截屏一次 将截取的图片post请求发送 根据响应判断图片是否保存到本地 保存时以当前时间命名 代码 BufferedImage类 import or
  • HTTP响应的结构是怎么样的?

    HTTP响应由三部分组成 状态行 响应头 响应正文 状态行 包括协议版本的Version 状态码 Status Code 回应短语 响应头 包括搭建服务器的软件 发送响应的时间 回应数据的格式等信息 响应正文 就是响应的具体数据 HTTP请
  • 二进制、八进制、十进制、十六进制之间的相互转换

    一 二进制 八进制 十六进制转换为十进制 方法 位权求和法 二进制用符号 B 表示 十进制用符号 D 表示 八进制用符号 O 表示 十六进制用符号 H 表示 100101 10111 B 1 2 5 0 2 4 0 2 3 1 2 2 0
  • Java获取当前时间的年月日时分秒方法

    相关内容 package com ob import java text ParseException import java text SimpleDateFormat import java util Calendar import j
  • java中 ‘\b‘ 回退符的使用

    退格符 b b是退格符的意思 将光标回退一个字符的位置 可以结合空白字符使用达到类似删除的效果 1 回退符 b 后面没有内容 的情况 原样输出 回退符 b后面 没有内容 则原样输出 System out println x b x 回退符后
  • violate关键字---java高并发

    内存模型相关概念 计算机在执行程序时 每条指令都是在CPU中执行的 而执行指令过程中 势必涉及到数据的读取和写入 由于程序运行过程中的临时数据是存放在主存 物理内存 当中的 这时就存在一个问题 由于CPU执行速度很快 而从内存读取数据和向内
  • ⛳ 面试题-单例模式会存在线程安全问题吗?

    目录 面试题 单例模式会存在线程安全问题吗 一 单例模式 简介 二 饿汉式 三 懒汉式 3 1 懒汉式 在调用 getInstance 的时候才创建对象 线程不安全 3 2 改造1 对懒汉式进行加锁改造 线程安全 3 3 改造2 对懒汉式继
  • 10 个牛逼的单行代码编程技巧,你会用吗?

    标题本文列举了十个使用一行代码即可独立完成 不依赖其他代码 的业务逻辑 主要依赖的是Java8中的Lambda和Stream等新特性以及try with resources JAXB等 1 对列表 数组中的每个元素都乘以2 Range是半开

随机推荐

  • JAVA基础之增删改查

    开发工具 eclipse 数据库 Oracle 项目分析 数据库的搭建 项目结构 一 主界面 采用无刷新的方法 该方法需要用到jQuery插件 界面展示 分页 删除 模糊查询 教员 班级 爱好 代码展示
  • 递推典型算法:猴子爬山,跳台阶,爬楼梯(牛客网)、魔法深渊(快手)----Python、Java

    递推算法的基本思想是把一个复杂的 庞大的计算过程转化为简单过程的多次重复 其首要问题是得到相邻的数据项之间的关系 即递推关系 以猴子爬山为例 1 问题的提出 一个顽猴在一座有30级太假的小山上爬山活跃 猴子上一步可跳1级或者3级 试求上山的
  • win10黑屏假死怎么解决

    现在很多用户都是使用的win10电脑 但是电脑使用久了之后出现一些问题时在所难免的 例如最近就有网友反映说自己的win10纯净版电脑出现了开机后黑屏假死的情况 该如何处理呢 赶紧看看吧 解决教程如下 1 win10系统开机的时候一直按F8直
  • 【Python】python使用docxtpl生成word模板

    python使用docxtpl生成word模板 python docxtpl包简单使用和实战 Python处理word docx文件 最近需要处理一些爬虫得到的数据来进行一些自动化报告的操作 因为需要生成的是word的报告 所以估选用doc
  • Mastering_Rust(译):内存,生命周期和借用(完+1)

    Rust让你 开发人员自己处理内存 但是 它可以帮助您完成内存分配的抽象和语言支持 它的生命周期 所有权和借用系统可能是您熟悉的C 世界的概念 Rust拥有所有这些 不仅仅是概念 而是语言以及编译时检查 使这一类最困难的运行时问题变得更容易
  • 神经网络调优 --- batch_size

    batchsize和收敛速度 性能的关系 一般来说 在合理的范围之内 越大的 batch size 使下降方向越准确 震荡越小 小的 bath size 引入的随机性更大 单次epoch耗时更久 且震荡大难以收敛 但大的batchsize容
  • SQL注入漏洞简介、原理及防护

    目录 1 SQL注入漏洞简介 2 SQL注入漏洞原理 3 SQL注入的分类 4 注入方法 5 SQL注入危害 6 SQL注入防护措施 1 SQL注入漏洞简介 SQL注入漏洞是Web层面最高位的漏洞之一 所谓SQL注入 就是通过把SQL命令插
  • Ubunto18.04安装完成后没有gcc、make、g++、无法访问域名等解决方法

    Ubunto18 04安装完成后没有gcc make g 无法访问域名等解决方法 今天新安装完虚拟机后又安装了Ubunto 然后就碰到了个恶心的事情 就是这是个纯净版 里面好多东西都没有 没有gcc make等等 按照其他博主的方法都不好使
  • 本地电脑与阿里云服务器之间实现文件传输

    文章目录 1 文件传输 1 1 服务器使用本地文件 1 2 使用FileZilla软件 1 2 1 服务端配置 1 2 2 客户端配置 1 2 3 问题及解决 1 2 3 1 bug 1 2 3 2 原因 1 2 3 3 解决 1 2 3
  • 解决“ warning C276: constant in condition expression“和“warning C294: unreachable code“两个告警提示

    好久不见 最近因为一些项目比较忙 都没怎么发文章了 今天有空就来分享一下自己之前遇到的两个告警 告警信息 首先 我们先来看一下这两个告警 第一个告警为 warning C276 constant in condition expressio
  • Go Web编程实战(3)----数据类型

    目录 前言 布尔型 数字类型 字符串类型 使用 byte修改 使用 rune修改 指针类型 指针的简单用法 修改指针值 复合类型 数组类型 结构体介绍 切片类型 从指定范围生成切片 重置切片 直接声明切片 Map 前言 Go语言数据类型包括
  • 设置idea控制台打印的日志输出到本地文件

    在idea的控制台很难看到日志 很快速的就刷过去了 而且日志多的话 很多就看不到了 所以我设置了一下idea把日志输出到文件 方便查看 1 在idea的菜单栏 找到这个向下的三角 点击 选择Edit Configurations 2 在打开
  • 官宣!玖章算术获评“浙江省创新型中小企业”

    近日 浙江省工业和信息化厅开展了 2023 第二季度创新型中小企业评价工作 经企业自评 地市审核 抽查 市经信局审核评价等程序 玖章算术以优秀的自主创新能力通过认定 成为浙江省 2023 年度创新型中小企业 创新型中小企业 是指具有较健全的
  • FISCO BCOS(五)———部署安装jdk1.8

    1 将下载的jdk1 8 0 162 linux x64 tar gz通过远程连接工具 放入 usr local 目录 然后解压 2 解压 tar zxvf jdk1 8 0 162 linux x64 tar gz 3 切换到jdk1 8
  • 闲聊——集成学习理论(Adaboost,随机森林理论与个人实战中的体会)

    本文通过简单的例子来引出算法本质 同时附上证明过程 目的是让感觉直接看证明推导很难的小伙伴们也能理解集成算法是怎样实现的 集成学习通过构建并结合多个学习器来完成学习任务 可获得比单一学习器更好的泛化性能 目前的集成学习方法大致可分为两类 第
  • 程序员常用十大算法之KMP算法

    程序员常用十大算法之KMP算法 一 应用场景 二 暴力匹配算法 2 1思路分析 2 2代码实现 三 算法介绍 四 KMP算法最佳应用 4 1字符串匹配问题 4 2思路分析图解 代码实现 本文是程序员常用十大算法的第一节 后面的算法总结都在博
  • JSON 驼峰转下划线

    import com fasterxml jackson databind PropertyNamingStrategy PropertyNamingStrategyBase public class MyCamemlToUnderline
  • MAC DOCKER无法ping通容器解决方案

    原因 解决方案 原因 先来看下LINUX的docker架构 docker是在linux内核容器基础上实现的 linux安装docker后 会创建一个为docker0的虚拟网卡 linux宿机与docker容器之间的通信 通过docker0虚
  • 高三计算机教案,2017高三信息技术教学计划

    信息技术是一门操作性和实践性强的课程 应注重培养学生的动手操作实践能力 提高学生的学习兴趣 达到学习的目的 下面是学习啦小编带来关于2017高三信息技术教学计划的内容 希望能让大家有所收获 2017高三信息技术教学计划 一 一 基本情况 1
  • violate关键字---java高并发

    内存模型相关概念 计算机在执行程序时 每条指令都是在CPU中执行的 而执行指令过程中 势必涉及到数据的读取和写入 由于程序运行过程中的临时数据是存放在主存 物理内存 当中的 这时就存在一个问题 由于CPU执行速度很快 而从内存读取数据和向内