专栏首页Java技术栈volatile关键字解析~高级java必问

volatile关键字解析~高级java必问

昨天我介绍了原子性、可见性、有序性的概念,那么今天就来见识下这些概念的主角-volatile关键字。

volatile基本介绍

volatile可以看成是synchronized的一种轻量级的实现,但volatile并不能完全代替synchronized,volatile有synchronized可见性的特性,但没有synchronized原子性的特性。可见性即用volatile关键字修饰的成员变量表明该变量不存在工作线程的副本,线程每次直接都从主内存中读取,每次读取的都是最新的值,这也就保证了变量对其他线程的可见性。另外,使用volatile还能确保变量不能被重排序,保证了有序性。

volatile只用修饰一个成员变量,如:private volatile balance;

volatile比synchronized编程更容易且开销更小,但具有一点的使用局限性,使用要相当小心,不能当锁使用。volatile不会像synchronized一样阻塞程序,如果是读操作远多于写操作的情况可以建议使用volatile,它会有更好的性能。

volatile使用场景

如果正确使用volatile的话,必须依赖下以下种条件:

1、对变量的写操作不依赖当前变量的值;

2、该变量没有包含在其他变量的不变式中。

第1个条件就说明了volatile不是原子性的操作,不能使用n++类似的计数器,它不是线程安全的。

1、状态的改变

有些场景肯定会有状态的改变,完成一个主线程的停止等。首先我们开启了一个无限循环的主线程,判断变量isStop变量是否为true,如果true的话就退出程序,否则就一直循环,所以这个isStop的值是别的线程改变的。

上面这段程序如果不加volatile的话会一直卡在循环,此时的线程拿到的值永远为false,加了volatile3秒后就输出stop,所以这段程序很好的解释了可见性的特点。

2、读多写少的情况

假设这样一种场景,有N个线程在读取变量的值,只有一个线程写变量的值,这时候就能保证读线程的可见性,又能保证写线程的线程安全问题。

像n++不是原子类的操作,其实可以通过synchronized对写方法锁住,再用volatile修饰变量,这样就保证了读线程对变量的可见性,又保证了变量的原子性。

如果n不加volatile,程序将一直循环,不能输出stop,也就是此时的线程拿到的值永远为0。当然不加volatile,对获取n的方法进行synchronized修饰也是能及时获取最新值的,但是性能会远低于volatile。

本文分享自微信公众号 - Java技术栈(javastack),作者:Java技术栈

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

原始发表时间:2017-06-24

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

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java 虚拟机对锁优化所做的努力

    作为一款公用平台,JDK 本身也为并发程序的性能绞尽脑汁,在 JDK 内部也想尽一切办法提供并发时的系统吞吐量。这里,我将向大家简单介绍几种 JDK 内部的 "...

    Java技术栈
  • 多线程并发神器--ThreadLocal

    什么是ThreadLocal 可以理解成线程本地变量,传统的线程对一个变量操作时操作的是同一个对象,也存在线程安全的问题。 ThreadLocal是一个变量的本...

    Java技术栈
  • 干货 | Tomcat 连接数与线程池详解

    在使用tomcat时,经常会遇到连接数、线程数之类的配置问题,要真正理解这些概念,必须先了解Tomcat的连接器(Connector)。

    Java技术栈
  • 每个学习多线程的Java程序员都必须掌握的volatile关键字解析

    volatile可以看成是synchronized的一种轻量级的实现,但volatile并不能完全代替synchronized,volatile有synchro...

    Java_老男孩
  • volatile变量

    关键字volatile是虚拟机提供的一种轻量级的同步机制,但在做多线程开发时,大部分的人都不太习惯喜欢用volatile,而是直接用关键字synchronize...

    吉林乌拉
  • The Myth of volatileJDK1.5之前的volatileJDK1.5之后的volatilevolatile足够了吗?volatile VS 锁结论

    大宽宽
  • JUC 多线程之 volatile 关键字

    但是JMM ( java内存模型 )规范必须保证:内存可见性,禁止指令重排(有序性),原子性。

    万能青年
  • volatile和Synchronized区别

    volatile和Synchronized区别 volatile Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进...

    xiangzhihong
  • C++核心准则CP.200:使用volatile只能表明该变量是非C++内存

    volatile is used to refer to objects that are shared with "non-C++" code or hard...

    面向对象思考
  • 【不要再背】volatile的可见性和原子性

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

    用户4143945

扫码关注云+社区

领取腾讯云代金券