java 内存模型之 volatile 核心原理与应用

本文详细探讨了 Java 中 volatile 变量的核心原理,包括它的可见性、有序性保证,以及与 synchronized 和 atomic 原子类的区别。通过对 volatile 的深入理解,读者可以更好地掌握在多线程环境下如何正确使用 volatile 变量。
摘要由CSDN通过智能技术生成

在阅读本文前,请思考以下的面试题?

  • volatile 是什么?

  • volatile 的特性

  • volatile 是如何保证可见性的?

  • volatile 是如何保证有序性的?

  • volatile 可以保证原子性吗?

  • 使用 volatile 变量的条件是什么?

  • volatile 和 synchronized 的区别

  • volatile 和 atomic 原子类的区别是什么?

这一章主要是讲解 volatile 的原理,在开始本文前,我们来看一张 volatile 的思维导图,先有个直观的认识。

什么是 volatile?

目前的操作系统大多数都是多 CPU,当多线程对一个共享变量进行操作时,会出现数据一致性问题

Java 编程语言允许线程访问共享变量,那么为了确保共享变量能被准确和一致的更新,线程应该确保通过排他锁单独获得这个变量,或者把这个变量声明成 volatile,可以理解 volatile 是轻量级的 synchronized。

使用 volatile 可以在 Java 线程内存模型确保所有线程看到这个变量的值是一致的,在多个处理器中保证了共享变量的“可见性”。

volatile 两核心三性质?

两大核心:JMM 内存模型(主内存和工作内存)以及 happens-before

三条性质:原子性,可见性,有序性

volatile 性质?

  1. 保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。(实现可见性)

  2. 禁止进行指令重排序。(实现有序性)

  3. 只能保证对单次读/写的原子性。i++ 这种操作不能保证原子性。(不能实现原子性)

  4. volatile 不会引起上下文的切换和调度

总结:volatile 保证了可见性和有序性,同时可以保证单次读/写的原子性

相关的 Cpu 术语说明

什么是可见性?

在单核 cpu 的石器时代,我们所有的线程都是在一颗 CPU 上执行,CPU 缓存与内存的数据一致性容易解决。因为所有线程都是操作同一个 CPU 的缓存,一个线程对缓存的写,对另外一个线程来说一定是可见的。

例如在下面的图中,线程 A 和线程 B 都是操作同一个 CPU 里面的缓存,所以线程 A 更新了变量 a 的值,那么线程 B 之后再访问变量 a,得到的一定是 a 的最新值(线程 A 写过的值)。

在多核 CPU 的时代,每颗 CPU 都有自己的缓存,这时 CPU 缓存与内存的数据一致性就没那么容易解决了,当多个线程在不同的 CPU 上执行时,这些线程操作的是不同的 CPU 缓存。比如下图中,线程 A 操作的是 CPU-1 上的缓存

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值