volatile原理

java 使用volatile修饰符是线程之间可以共享变量,一个变量用volatile修饰,意味着在多个线程情况下此变量是可见并且是一致的;在特定情况下volatile比锁拥有更好的性能

volatile int count;
volatile 原理

介绍volatile原理之前,先来简单了解下java的内存模型

我们在执行我们的程序的时候,jvm根据自己的内存模型会把内存分为:方法区 Method Area,虚拟机栈VM Stack,本地方法栈Native Method Stack,堆Heap,程序计数器 Program Counter Register

方法区

是被所有的线程共享的一块内存区域。它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

虚拟机栈

每个方法执行的同时会创建一个栈帧,栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。

本地方法栈

本地方法栈与虚拟机栈所发挥的作用是非常相似的,它们之间的区别不过是虚拟机栈为虚拟机执行Java方法服务(也就是字节码),而本地方法栈为虚拟机使用到的Native方法服务。

堆Heap

Java堆是被所有的线程共享的一块内存区域,在虚拟机启动时创建。

程序计数器

程序计数器可以看做是当前线程所执行的字节码的行号指示器

详细参考:https://www.jianshu.com/p/7ebbe102c1ae

volatile数据一致性

从方法区定义可知一个变量count声明为volatile类型,则意味这这个变量将存储在方法区;而线程运行时,线程会单独拷贝一份count变量到自己的内存区域,这个内存区域也就是虚拟机栈,画个图
在这里插入图片描述
每个线程都拷贝了一份count变量到自己的内存区域,那是怎么做到一致性的?

在多线程情况下,如果某一个线程要对volatile 变量修改,首先运行该线程的cpu会锁定方法区变量内存区域,保证做到数据修改的原子性;那现在问题就来了,其他线程是怎么获得最新的数据?运行其他线程的cpu有会嗅探总线上该内存区域的地址是否被修改;如果该线程缓存的变量副本所指向方法区的地址发生了变化,则将自己缓存的数据设置成无效,等待线程使用到该变量的时候,会从新从方法区获得一份新的数据,同步到本地线程的缓存区域,这样就volatile变量就做到了多线程的可见以及一致性

  • 8
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值