多线程复习总结之解析Volatile关键字

本文探讨了Java内存模型中volatile关键字的作用,解释了其如何确保可见性和有序性,以及为何在并发编程中使用。通过实例说明了volatile与原子性的区别,并提到了其使用场景及限制。涵盖了内存屏障、synchronized和volatile性能对比等内容。
摘要由CSDN通过智能技术生成

引言

在了解volatile之前,首先需要了解java的内存模型。

Java内存模型(JMM)

在 JDK1.2 之前,Java 的内存模型实现总是从主存(即共享内存)读取变量,是不需要进行特别的注意的。但是在当前的 Java 内存模型下,线程把变量保存在本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写。这就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量值的拷贝,从而导致数据的不一致问题。
在这里插入图片描述
要解决这个问题,就需要把变量声明为volatile,表明告诉 JVM 说,这个变量是共享且不稳定的,每次使用它都到主存中进行读取。【即保证变量的可见性】
在这里插入图片描述

并发编程的三个重要特性

原子性 : 一个操作或者多个操作,要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。(synchronized+lock 可以保证代码片段的原子性)

可见性 :当一个变量对共享变量进行了修改,那么另外的线程都是立即可以看到修改后的最新值。(volatile 关键字可以保证共享变量的可见性)

有序性 :程序执行的顺序按照代码的先后顺序执行。(volatile 关键字可以禁止指令进行重排序优化)
【注】在Java内存模型中,允许编译器和处理器对指令进行重排序,但是重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。

volatile的原理和实现机制

“观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现,加入volatile关键字时,会多出一个lock前缀指令”

lock前缀指令实际上相当于一个内存屏障(也成内存栅栏),内存屏障会提供3个功能:

  • 它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面
  • 它会强制将对缓存的修改操作立即写入主存;
  • 如果是写操作,它会导致其他CPU中对应的缓存行无效。

volatile使用场景

synchronized关键字是防止多个线程同时执行一段代码,但是会很影响程序执行效率。

而volatile关键字在某些情况下性能要优于synchronized,但是volatile关键字是无法替代synchronized关键字的,因为volatile关键字无法保证操作的原子性。

通常来说,使用volatile必须具备以下2个条件:
1)对变量的写操作不依赖于当前值
2)该变量没有包含在具有其他变量的不变式中

附:参考资料

Java并发编程:volatile关键字解析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

--流星。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值