专栏首页Java后端技术栈cwnait【不要再背】volatile的可见性和原子性

【不要再背】volatile的可见性和原子性

volatile作用

  • 保证内存可见性
  • 防止指令重排序
  • 注意:并不保证原子性

可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值

内存可见性

volatile保证可见性的原理是在每次访问变量时候都会进行一次刷新,因此每次访问都是准没存中最新的版本,所以volatile关键字的作用之一就是保证变量修改的实时可见性

使用volatile使用必须的条件

  1. 对变量的写入操作不依赖变量的当前值,或者你能确保只有单个线程更新变量的值
  2. 该变量没有包含在具有其他变量的不变式中

volatile使用建议

  • 在两个或者更多的线程需要访问的成员变量上使用volatile,当腰访问的变量已在shnchronized代码块中或者常量时,咱们就没要使用volatile
  • 由于使用volatile屏蔽调JVM中必要的代码优化,所以在效率上比较低,因此一定在必要时才使用此关键字

volatile VS synchronized

1:volatile不会进行枷锁操作,volatile变量是一种微弱的同步机制在访问volatile变量时不会执行解锁操作,因此不会执行线程阻塞,因此volatile变量是一种比synchronized关键字更轻量级的同步机制。

2:volatile变量作用类似于同步变量读写操作,从内存可见性的角度来看,写入volatile变量相当于退出同步代码块,而读取volatile比那辆相当于进入同步代码块。

3:volatile不如synchronized安全,在代码中如果过度使用volatile变量来控制状态的可见性,通常会比使用锁的代码更脆弱,也更难以理解,仅当volatile变量能简化代码的实现以及对同步策略的验证时,才应该使用volatile,一般来说,使用同步机制会更安。

4:volatile无法同事保证内存可见性和原子性,加锁机制(同步机制)既可以确保可见性又可以确保原子性,而volatile只能保证可见性,原因是声明为volatile的简单变量如果昂墙纸与该变量以前的值相关,那么volatile关键字不起作用,也就是说下面的表达式都不是院子操作的:count++,i++。

可见性demo证明

输出,一直执行中,证明这个一个线程修改后其他线程并不知道,导致while循环一直执行

给quit变量加一个volatile修饰

输出:

不保证原子性demo证明

输出结果多变:

第一种结果

第二种结果

第三种

第四种

本文分享自微信公众号 - Java后端技术栈(t-j20120622),作者:lawt

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-06-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 你的也是我的。3例ko多线程,局部变量透传

    java中的threadlocal,是绑定在线程上的。你在一个线程中set的值,在另外一个线程是拿不到的。如果在threadlocal的平行线程中,创建了新的子...

    用户4143945
  • 再也不敢使用集合默认初始化值了

    集合初始化通常进行分配容量、设定特定参数等相关工作。我们以使用频率相对较高的ArrayList和HashMap为例,简要说明初始化的相关工作,并解释为什么在任何...

    用户4143945
  • 快速入门正向代理与反向代理

    比如访问某些国外网站,可能需要购买vpn,并且vpn是在用户浏览器端设置的(并不是在远端的服务器设置)。浏览器先访问vpn地址,vpn地址转发请求,并最后将请求...

    用户4143945
  • 【java并发编程实战3】解密volatilevolatile的使用场景

    根据 as if serial原则,它强调了单线程。那么多线程发生重排序又是怎么样的呢?

    yukong
  • C++雾中风景13:volatile解惑

    volatile这个单词在英文之中的意思是:易变的,不稳定的的含义。所以顾名思义,一旦变量通过了volatile关键词修饰之后,说明变量是易变的和不稳定的。而C...

    HappenLee
  • 围绕一个 volatile 关键字居然可以问出来 16 个问题

    对于 Java 每次面试就会想到多线程,多线程问题基本跑不了要问一下 volalite 关键字,可是我万万没想到居然一个 volatile 关键字可以连续问题出...

    Java团长
  • Java 理论与实践: 正确使用 Volatile 变量

    Java 语言中的 Volatile 变量可以被看作是一种 “程度较轻的 synchronized”;与 synchronized 块相比,volatile 变...

    哲洛不闹
  • AtomicIntegerFieldUpdater

    对于volatile变量,写的时候会将线程本地内存的数据刷新到主内存上,读的时候会将主内存的数据加载到本地内存里,所以可以保证可见行和单个读/写操作的原子性。但...

    yiduwangkai
  • Java 并发编程:volatile的使用及其原理

    用户2140019
  • Java 并发编程:volatile的使用及其原理

    用户2140019

扫码关注云+社区

领取腾讯云代金券