转载请标明:https://www.cnblogs.com/tangZH/p/15113505.html

一、如果一个变量被volatile关键字修饰,那么所有线程都是可见的。所谓可见就是,当一条线程修改了这个变量值,新值对于其他线程来时是立即可见的; 而普通变量不能做到这一点。

1、现在计算机缓存架构:

CPU与内存之间存在缓存。

2、Java内存模型(JMM:java memory model)。

这里的主内存再java中相当于堆。

在不同线程中操作同一个变量,实际上操作的是各自工作内存中的一个副本。

3、JMM的8大原子操作:

4、过程:

当线程1需要用到变量a的时候,会通过read操作将a读入临时区,然后再通过load操作载入到变量副本中。

需要用这个变量的话就用use操作。

当线程2需要用到这个变量的时候也是一样的过程。

如果变量没有加volatile,那么两个线程用到的变量实际上是不一样的。

加上volatile之后:

会强制将缓存刷新到主内.会激活总线嗅探器。当我们改变该变量在副本里面的值后写回主内存时,总线监听到就会去通知其余线程将该变量的副本移除,然后再改变主内存中的值。这样当其他线程再次用到该变量的时候就会重新从主内存里面拿了。

总线嗅探器机制也被叫做MESI缓存一致性协议。

二、Volatile能够禁止指令重排。

1、先看对象的生成过程,底层的指令如下:

(1)、new 一个obj,此时内存里面的初始值为0.

(2)、再栈里面生成一个引用。

(3)、执行构造方法,将值改变。

(4)、将引用指向内存。

而编译器会进行优化,编译器优化是指,在不改变原来语义的情况下,通过调整语句顺序,来让程序运行的更快。比如将(3)、(4)交换顺序不会有什么影响(单线程情况下)。

具体例子看:

单例模式的双重检测

Volatile关键字原理的更多相关文章

  1. java:volatile关键字原理

    volatile说明 在变量中声明后,能够在所有线程中共享改变量.并且volatile关键字能防止指令重排,即程序读取到volatile时,则不会将程序执行顺序修改. 先了解下内存模型 cpu内存模型 ...

  2. JUC回顾之-volatile的原理和使用

    1.计算机内存模型的相关概念 计算机在执行程序时,每条指令都是在CPU中执行的,在指令的执行过程中,涉及到数据的读取和写入.由于程序在运行的过程中数据是放在"主存"中的, 由于数据 ...

  3. Java单例模式和volatile关键字

    单例模式是最简单的设计模式,实现也非常"简单".一直以为我写没有问题,直到被 Coverity 打脸. 1. 暴露问题 前段时间,有段代码被 Coverity 警告了,简化一下代码 ...

  4. Java并发——volatile关键字的使用

    volatile关键字的使用volatile关键字原理适合使用volatile关键字的情况当且仅当满足以下所有条件时,才==应该==使用volatile关键字:volatile关键字的作用volati ...

  5. 就是要你懂Java中volatile关键字实现原理

    原文地址http://www.cnblogs.com/xrq730/p/7048693.html,转载请注明出处,谢谢 前言 我们知道volatile关键字的作用是保证变量在多线程之间的可见性,它是j ...

  6. Java的 volatile关键字的底层实现原理

    我们知道volatile关键字的作用是保证变量在多线程之间的可见性,它是java.util.concurrent包的核心,没有volatile就没有这么多的并发类给我们使用.本文详细解读一下volat ...

  7. 【转】Java学习---Java中volatile关键字实现原理

    [原文]https://www.toutiao.com/i6592879392400081412/ 前言 我们知道volatile关键字的作用是保证变量在多线程之间的可见性,它是java.util.c ...

  8. volatile关键字的作用、原理

    在只有双重检查锁,没有volatile的懒加载单例模式中,由于指令重排序的问题,我确实不会拿到两个不同的单例了,但我会拿到"半个"单例. 而发挥神奇作用的volatile,可以当之 ...

  9. 面试题:volatile关键字的作用、原理

    在只有双重检查锁,没有volatile的懒加载单例模式中,由于指令重排序的问题,我确实不会拿到两个不同的单例了,但我会拿到“半个”单例. 而发挥神奇作用的volatile,可以当之无愧的被称为Java ...

  10. Java中volatile关键字实现原理

    原文地址http://www.cnblogs.com/xrq730/p/7048693.html,转载请注明出处,谢谢 前言 我们知道volatile关键字的作用是保证变量在多线程之间的可见性,它是j ...

随机推荐

  1. css3只需一招,将网站变成灰色的

    今天大家在浏览B站,腾讯视频,等网站时,有没有发现一个现象,网站变成灰色的了. 是不是跟平常不一样了呢,这是因为今天(2020.4.4)是全国哀悼日, 所以网站这些就变成灰色的呢. 我去看了一下腾讯的 ...

  2. (数据科学学习手札157)pandas新增case_when方法

    本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 大家好我是费老师,pandas在前不久更新的2. ...

  3. 微信小程序-获取用户位置

    首先我要提供几个文档的链接地址: 首先是官方文档的获取用户位置的API文档地址: 官方文档地址:https://developers.weixin.qq.com/miniprogram/dev/api ...

  4. HarmonyOS实战[一]——原理概念介绍安装:基础篇

    [本文正在参与"有奖征文|HarmoneyOS征文大赛"活动] 相关文章: HarmonyOS实战[一]--原理概念介绍安装:基础篇 HarmonyOS实战[二]-超级详细的原子化 ...

  5. Walrus 实用教程|Walrus + Gitlab,打通CI/CD 自动化交付!

    Walrus file 是 Walrus 0.5 版本推出的新功能,用户可以通过一个非常简洁的 YAML 描述应用或基础设施资源的部署配置,然后通过 Walrus CLI 执行 walrus appl ...

  6. vue-router.esm.js:2065 Uncaught (in promise) Error: Redirected when going from "/login?redirect=%2Fhome" to "/home" via a navigation guard.

    原因:   vue-router路由版本更新产生的问题,导致路由跳转失败抛出该错误; 真正的原因是由于返回了一个Promise对象, 正常的跳转由then方法执行 当正常的路由跳转, 被"路 ...

  7. SqlDapperEasyUtil:.NET CORE下的Dapper封装操作类

    之前介绍了基于Dapper二次封装了一个易用的ORM工具类:SqlDapperUtil,这个在.NET FX下还是比较好用的,现在都流行.NET CORE,故我这边再次进行精简修改,以便适应.NET ...

  8. Python中os.walk函数说明

    这个函数对于文件方面的遍历等其他方面的操作来说功能很强大,比如批量修改文件名.批量移动文件.将所有不在一个文件夹下的文件移动到同一个文件夹下等等. 这个其实很简单的,用一个示例就能明白这个函数的具体用 ...

  9. Linux centos7.6 在线及离线安装postgresql12 详细教程(rpm包安装)

    一.在线安装 官网找到对应的版本 PostgreSQL:  https://www.postgresql.org/ 1.配置yum源 sudo yum install -y https://downl ...

  10. Sliver C2 实战 vulntarget-f

    ‍ 网络拓扑 host ip1 ip2 ubuntu(自用) 192.168.130.14 / centos 192.168.130.3 10.0.10.2 ubuntu1 10.0.10.3 10. ...