前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >volatile关键字

volatile关键字

作者头像
用户4919348
发布2019-04-02 10:50:11
3940
发布2019-04-02 10:50:11
举报
文章被收录于专栏:波波烤鸭波波烤鸭

  volatile关键字是我们经常在面试过程中碰到的一个问题,本文来介绍下这个关键字

原则性,可见性,有序性

  在具体介绍volatile之前我们先来看下这三个概念

原子性

  原子性通常指多个操作不存在只执行一部分的情况,如果全部执行完成那没毛病,如果只执行了一部分,那对不起,你得撤销(即事务中的回滚)已经执行的部分。

可见性

  当多个线程访问同一个变量a时,线程1修改了变量a的值,线程1、线程2…线程n能够立即读取到线程1修改后的值.

有序性

  即程序执行时按照代码书写的先后顺序执行。在Java内存模型中,允许编译器和处理器对指令进行重排序,但是重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。

volatile关键字

  关键字volatile是java虚拟机提供的最轻量级的同步机制。单词翻译过来是“不稳定,反复无常”.描述的也很形象,说明被声明为volatile的变量很容易被改变。当一个变量被声明为了volatile类型后它就具备了两种特性:

  1. 保证此变量对所有线程的可见性,这里的可见性指的是当一条线程修改了这个变量的值,新值对于其他线程来说是可以立即得知的,而普通变量做不到这点。
  2. 禁止指令重排序优化。普通变量仅仅会保证在该方法的执行过程中所有依赖赋值结果的地方都能获取到正确的结果,而不能保证变量赋值操作的顺序和程序代码的执行顺序一致,而volatile变量能保证变量前后的执行顺序。

接下来看下Java内存模式对Volatile制定的特殊的规则,假设T表示一个线程,V和W分别表示两个volatile型变量,那么在进行read,load,use,assign,store和write操作时需要满足如下规则:

  1. 只有当线程T对变量V执行的前一个动作是load的时候,线程T才能对变量V执行use动作,并且,只有当线程T对变量V执行的后一个动作是use的时候,线程T才能对变量V执行load动作,线程T对变量V的use动作可以认为是和线程T对变量V的load、read动作相关联,必须连续一起出现(这条规则要求在工作内存中,每次使用V前都必须先从主内存中刷新最新的值,用于保证能看见其他线程对变量V所修改后的值)。
  2. 只有当线程T对变量V执行的前一个动作是assign的时候,线程T才能对变量V执行store动作,并且,只有当线程T对变量V执行的后一个动作是store的时候,线程T才能对变量V执行assign动作,线程T对变量V的assign动作可以认为是和线程T对变量V的store、write动作相关联,必须连续一起出现,(这条规则要求在工作内存中每次修改V后都必须立刻同步回主内存中,用于保证其他线程可以看到自己对变量V的修改)
  3. 假定动作A是线程T对变量V实施的use或者assign动作,假定动作F是和动作A相关联的load或者store动作,假定动作P是和动作F相应的对变量V的read或者write动作,类似的,假定B是线程T对变量W实施的use或者assign动作,假定动作G是和动作B相关联的load或者store动,假定动作Q是和动作G相应的对变量W的read或write动作,如果A先于B,那么P先于Q,(这条规则要求volatile修饰的变量不会被指令重排序优化,保证代码的执行顺序与程序顺序相同)

参考《深入理解Java虚拟机》

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年03月11日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 原则性,可见性,有序性
    • 原子性
      • 可见性
        • 有序性
        • volatile关键字
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档