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的值是别的线程改变的。

image.png

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


2、读多写少的情况


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


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

image.png

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


推荐去我的博客阅读更多:


1.Java JVM、集合、多线程、新特性系列教程


2.Spring MVC、Spring Boot、Spring Cloud 系列教程


3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程


4.Java、后端、架构、阿里巴巴等大厂最新面试题


觉得不错,别忘了点赞+转发哦!

目录
相关文章
|
3天前
|
安全 前端开发 Java
10:基于Servlet模拟用户登录功能的实现与解析-Java Web
10:基于Servlet模拟用户登录功能的实现与解析-Java Web
16 3
|
5天前
|
供应链 Java API
Java 8新特性解析及应用区块链技术在供应链管理中的应用与挑战
【4月更文挑战第30天】本文将深入探讨Java 8的新特性,包括Lambda表达式、Stream API和Optional类等。通过对这些新特性的详细解析和应用实例,帮助读者更好地理解和掌握Java 8的新技术。
|
5天前
|
存储 安全 Java
【亮剑】Java并发编程中的四个关键字:ThreadLocal、Volatile、Synchronized和Atomic
【4月更文挑战第30天】Java并发编程涉及`ThreadLocal`、`Volatile`、`Synchronized`和`Atomic`四个关键机制。`ThreadLocal`为每个线程提供独立变量副本;`Volatile`确保变量可见性,但不保证原子性;`Synchronized`实现同步锁,保证单线程执行;`Atomic`类利用CAS实现无锁并发控制。理解其原理有助于编写高效线程安全代码。根据业务场景选择合适机制至关重要。
|
6天前
|
安全 Java API
Java 8新特性深度解析
【4月更文挑战第30天】本文将深入探讨Java 8的新特性,包括Lambda表达式、Stream API、Optional类等,以及这些新特性如何改变我们编写Java代码的方式。
|
6天前
|
Java 编译器
【Java探索之旅】this 关键字 解决你的成员变量困惑
【Java探索之旅】this 关键字 解决你的成员变量困惑
14 0
|
6天前
|
算法 Java
【Java探索之旅】运算符解析 算术运算符,关系运算符
【Java探索之旅】运算符解析 算术运算符,关系运算符
14 0
|
3天前
|
存储 缓存 前端开发
Java串口通信技术探究3:RXTX库线程 优化系统性能的SerialPortEventListener类
Java串口通信技术探究3:RXTX库线程 优化系统性能的SerialPortEventListener类
15 3
|
3天前
|
Java
JAVA难点包括异常处理、多线程、泛型和反射,以及复杂的分布式系统知识
JAVA难点包括异常处理、多线程、泛型和反射,以及复杂的分布式系统知识。入坑JAVA因它的面向对象特性、平台无关性、强大的标准库和活跃的社区支持。
15 2
|
4天前
|
Java 调度 开发者
Java中的多线程编程:基础与实践
【5月更文挑战第2天】本文将深入探讨Java中的多线程编程,从基础概念到实际应用,为读者提供全面的理解和实践指导。我们将首先介绍线程的基本概念和重要性,然后详细解析Java中实现多线程的两种主要方式:继承Thread类和实现Runnable接口。接着,我们将探讨线程同步的问题,包括synchronized关键字和Lock接口的使用。最后,我们将通过一个实际的生产者-消费者模型来演示多线程编程的实践应用。
|
4天前
|
安全 Java 程序员
Java中的多线程编程:从理论到实践
【5月更文挑战第2天】 在计算机科学中,多线程编程是一项重要的技术,它允许多个任务在同一时间段内并发执行。在Java中,多线程编程是通过创建并管理线程来实现的。本文将深入探讨Java中的多线程编程,包括线程的概念、如何创建和管理线程、以及多线程编程的一些常见问题和解决方案。
13 1

推荐镜像

更多