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

简介: 昨天我介绍了原子性、可见性、有序性的概念,那么今天就来见识下这些概念的主角-volatile关键字。volatile基本介绍volatile可以看成是synchronized的一种轻量级的实现,但volatile并不能完全代替synchronized,volatile有synchronized可见性的特性,但没有synchronized原子性的特性。

昨天我介绍了原子性、可见性、有序性的概念,那么今天就来见识下这些概念的主角-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。

相关文章
|
22小时前
|
Java 程序员 API
Java 8新特性之Lambda表达式与Stream API的深度解析
【5月更文挑战第12天】本文将深入探讨Java 8中的两个重要新特性:Lambda表达式和Stream API。我们将从基本概念入手,逐步深入到实际应用场景,帮助读者更好地理解和掌握这两个新特性,提高Java编程效率。
11 2
|
1天前
|
监控 Linux 数据处理
|
2天前
|
XML JavaScript Java
详解Java解析XML的四种方法
详解Java解析XML的四种方法
|
3天前
|
Java
解析java中的数组
解析java中的数组
10 3
|
4天前
|
存储 Java 程序员
Java面向对象编程的基础概念解析
Java面向对象编程的基础概念解析
13 0
|
4天前
|
缓存 Java 编译器
JMM内存模型 volatile关键字解析
JMM内存模型 volatile关键字解析
10 0
|
5天前
|
分布式计算 Java API
Java8 Lambda实现源码解析
Java8的lambda应该大家都比较熟悉了,本文主要从源码层面探讨一下lambda的设计和实现。
|
6天前
|
缓存 测试技术 Android开发
深入了解Appium:Capability 高级配置技巧解析
Appium 提供多种进阶配置项以优化自动化测试,如 deviceName 作为设备别名,udid 确保选择特定设备,newCommandTimeout 设置超时时间,PRINT_PAGE_SOURCE_ON_FIND_FAILURE 在错误时打印页面源,以及测试策略中的 noReset、shouldTerminateApp 和 forceAppLaunch 控制应用状态和重启。这些配置可提升测试效率和准确性。
16 2
|
10天前
|
安全 前端开发 Java
10:基于Servlet模拟用户登录功能的实现与解析-Java Web
10:基于Servlet模拟用户登录功能的实现与解析-Java Web
24 3
|
12天前
|
供应链 Java API
Java 8新特性解析及应用区块链技术在供应链管理中的应用与挑战
【4月更文挑战第30天】本文将深入探讨Java 8的新特性,包括Lambda表达式、Stream API和Optional类等。通过对这些新特性的详细解析和应用实例,帮助读者更好地理解和掌握Java 8的新技术。

推荐镜像

更多