现象

 private static boolean is = false;public static void main(String[] args) {new Thread(new Runnable() {@Overridepublic void run() {System.out.println("thread 1 start");while (!is) {}System.out.println("thread 1 end");}}).start();try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}new Thread(new Runnable() {@Overridepublic void run() {System.out.println("thread 2 start");is = true;System.out.println("thread 2 end");}}).start();}
}

以上代码的系统输出内容

现在,对我们的变量加入voliate关键字后输出对比

从上面的对比我们不难看出,没有加入voliate的时候,我们的程序一直没有退出,因为线程1一直处于死循环。
也就是说,线程2改变的is值没能成功传递到线程1

本质

要说明这个问题,得从jvm的工作内存和主内存说起
下面是copy的一段内容
JVM将内存组织为主内存和工作内存两个部分。

主内存是所有的线程所共享的,主要包括本地方法区和堆。

每个线程都有一个工作内存不是共享的,工作内存中主要包括两个部分:

     1:一个是属于该线程私有的栈;2:对主存部分变量拷贝的寄存器(包括程序计数器PC和cup工作的高速缓存区)。

1.所有的变量都存储在主内存中(虚拟机内存的一部分),对于所有线程都是共享的

2.每条线程都有自己的工作内存,工作内存中保存的是主存中某些变量的拷贝,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存中的变量。
3.线程之间无法直接访问对方的工作内存中的变量,线程间变量的传递均需要通过主内存来完成,即:线程、主内存、工作内存。

画个图来理解一下这段话的意思

图解


当A和B对主内存的变量进行操作的时候,它们并不是直接操作这个X,而是要先经过一次内存拷贝,将X拷贝到自己的工作内存中

当某个线程对X进行写入操作的时候,是对自己的X副本进行写入,然后再将这个副本的内容交给系统写入到主内存。但是呢,如果这个时候,B已经从主内存中读取了X变量了,那么B每次拿,都是拿自己的X的副本,也就是之前的值

所以,B线程是没办法拿到修改后的值。

关于voliate
写过程: 当一个线程修改某个voliate变量的值的时候,JMM会把该线程对应的本地内存中的共享变量值刷新到主内存。
读过程: 当一个线程读取某个voliate变量的值的时候,JMM会把该线程对应的本地内存置为无效,线程接下来将从主内存读取共享变量。
这样就保证了,B线程能够得到修改后的值了。

关于voliate关键字相关推荐

  1. java中变量 关键字_基于java的voliate关键字详解

    voliate关键字的作用: 一.内存可见性 基于缓存一致性协议,当用voliate关键字修饰的变量改动时,cpu会通知其他线程,缓存已被修改,需要更新缓存.这样每个线程都能获取到最新的变量值. 二. ...

  2. voliate关键字

    voliate关键字详解: 1.内存模型相关概念 物理计算机内存访问图: 任何计算都是在CPU内处理的,那么也就必须涉及到数据读写,但是CPU每次都要和主内存交互读写数据效率太低了,于是有了高速缓存. ...

  3. voliate关键字原理

    被volatile修饰的变量在编译成字节码文件时会多个lock指令,该指令在执行过程中会生成相应的内存屏障,以此来解决可见性跟重排序的问题. 预备知识 指令重排序 为什么到指令重排序:一般来说,处理器 ...

  4. C++中voliate关键字

    voliate变量是随时变化的,用voliate修饰的运算,编译器不进行优化,以免出错. 对于一个普通变量,为提高存取速率,编译器会先将变量的值存储在一个寄存器中,以后再取变量值时,就存寄存器中取出. ...

  5. C语言中voliate关键字的作用

    一个变量用voliate关键字修饰,是要告诉编译器,这个变量的值随时可能发生变化,所以编译器每次都必须从变量对应的内存地址中获取该变量的值. voliate的常用方式: 当一个变量表示某寄存器的值时, ...

  6. Voliate关键字的作用

    Voliate关键字主要有以下两个作用: 一:内存可见性 基于缓存一致性协议,当系统或者程序中某个变量发生修改时,此时cpu会同时其他线程,告诉被通知的线程缓存内容已经被修改,通知i线程需要更新缓存, ...

  7. 多线程 - voliate 关键字

    介绍 volatile 是 Java 中的关键字,用于修饰变量.它的作用是强制对被修饰的变量的写操作立即刷新到主存中,并强制对该变量的读操作从主存中读取最新的值,而不是使用缓存中的值. 作用 保证变量 ...

  8. java voliate关键字_java中voliate关键字有什么用?

    1.保证内存可见性 内存可见性,即线程A对volatile变量的修改,其他线程获取的volatile变量都是最新的. 说到内存可见性就必须要提到Java的内存模型,如下图所示: 如上图所示,所有线程的 ...

  9. voliate 关键字

    voliate cpu术语定义 术语 英文单词 术语描述 内存屏障 cache barriers 处理器的指令 , 用于实现对内存操作的顺序限制 原子操作 atomic opers 不可中断的一个操作 ...

最新文章

  1. python线程信号量semaphore
  2. 一文搞懂C语言typedef关键字
  3. WDA 程序文本翻译OTR
  4. HTMLTESTRunner自动化测试报告增加截图功能
  5. 如何将composer设置为全局变量?
  6. 《Kafka权威指南》读书笔记1 初始Kafka
  7. MagicDraw-状态机图
  8. 看看雅虎助手是如何“兔子”和“360安全卫士”的
  9. android 监听连续点击,android基础之点击监听器的2种监听实现
  10. 一生要知道的100幅世界名画
  11. win10系统 Windows 资源保护找到了损坏文件 无法修复的有效解决方法
  12. CST Studio Suite 2020 安装教程
  13. Laravel OAuth2 (一) ---简单获取用户信息
  14. 转型经验分享|年过30的传统汽车人,如何转型做自动驾驶
  15. sql语句 四表联查
  16. Rocket mq的一些介绍
  17. 南京邮电大学网络攻防平台WriteUP——WEB(上)
  18. Pandas常用方法一
  19. 旋转向量与旋转矩阵的相互转化
  20. Django MVT详细说明(三)模板T

热门文章

  1. Task03: 变量、常量、枚举(1天) 组队学习 Go编程语言
  2. RocketMQ配置全解(含ACL、Dashboard配置)
  3. 基于 RabbitMQ 的实时消息推送
  4. HBase学习笔记(二)——LSM树(Log-Structured Merge-Tree)是什么?
  5. 转移到ios下载安卓_转移到ios下载官方app-转移到ios手机版v3.0.1 安卓版 - 极光下载站...
  6. Dim i% 中的 %
  7. 小程序原生 详解实现腾讯地图标点和路线规划和距离计算
  8. 微信域名检测采用官方接口
  9. MSP432库函数输出多路任意占空比PWM波
  10. 卸载VMware清理干净卸载残余方法