volatile 关键字说明

简介: volatile 关键字说明

volatile 变量修饰的共享变量进行写操作前会在汇编代码前增加 lock 前缀:

1),将当前处理器缓存行的数据写回到系统内存;

2),这个写会内存的操作会使其它 cpu 缓存该内存地址的数据无效。

 

Java 语言 volatile 关键字可以用一句贴切的话来描述 “ 人皆用之,莫见其形 “。理解 volatile 对理解它对理解 Java 的整个多线程的机制非常有帮助。

 

JVM 内存结构中有一个非常重要的内存区域叫做线程栈 , 每个线程的栈大小可以通过设置 JVM 参数-Xss, -Xss128k 表示每个线程堆栈大小为 128K,JDK1.5 默认值为 1M。

 

线程栈内存存储了基本类型变量和对象引用,当访问了对象的某一实例变量时,通过在栈中获得对象引用再获取变量的值,然后将变量的值拷贝至线程的工作内存。

 

每个线程 (处理器) 都有工作内存,工作内存存了该线程以读写共享变量的副本。工作内存是 JMM 抽象概念 , 并不真实存在。

 

它涵盖了缓存、写缓冲区、寄存器和其它硬件和编译器优化。

 

1),read and load 从主存复制变量到当前工作内存;

2),use and assign 执行代码,改变共享变量值;

3),store and write 用工作内存数据刷新主存相关内容;

4),其中 use and assign 可以多次出现。

 

但是这一些操作并不是原子性,也就是在 read load 之后,如果主内存 count 变量发生修改之后,线程工作内存中的值由于已经加载,不会产生对应的变化,所以计算出来的结果会和预期不一样。

 

可见性指的是一个线程对变量的写操作对其他线程后续的读操作可见。

 

由于现代 CPU 都有多级缓存,CPU 的操作都是基于高速缓存的,而线程通信是基于内存的,这中间有一个 Gap, 可见性的关键还是在对变量的写操作之后能够在某个时间点显示地写回到主内存,这样其他线程就能从主内存中看到最新的写的值。volatile,synchronized(隐式锁), 显式锁,原子变量这些同步手段都可以保证可见性。可见性底层的实现是通过加内存屏障实现的:

1),写变量后加写屏障,保证 CPU 写缓冲区的值强制刷新回主内存;

2),读变量之前加读屏障,使缓存失效,从而强制从主内存读取变量最新值。

总结: 在并发环境保证有序性、可见性,但原子性没办法保证。

相关文章
|
7月前
|
缓存 编译器 C语言
一起来探讨volatile关键字
在C语言中,volatile是一个关键字,用于告诉编译器不要对被声明为volatile的变量做优化,以确保每次对该变量的读写都直接操作内存。
|
缓存 安全 Java
【volatile关键字】
【volatile关键字】
|
4月前
|
存储 Java 编译器
|
存储 Java
浅谈Volatile关键字
该篇文章用来总结笔者对于Volatile关键字的理解,并不会太过深入的探讨。
139 0
浅谈Volatile关键字
|
SQL 缓存 Java
Volatile关键字介绍
Volatile关键字介绍
Volatile关键字介绍
|
存储 缓存 Java
volatile关键字再理解
volatile关键字再理解
volatile关键字再理解
|
编译器 程序员 C语言
C语言关键字详解(五)带你全面了解 volatile 关键字
C语言关键字详解(五)带你全面了解 volatile 关键字
379 0
C语言关键字详解(五)带你全面了解 volatile 关键字
|
SQL 缓存 安全
深入理解volatile关键字
深入理解volatile关键字
199 0
深入理解volatile关键字
|
缓存 前端开发 Java
volatile关键字有什么用?
volatile关键字有什么用?
volatile关键字有什么用?
|
缓存 安全 算法
你应该知道的 volatile 关键字(上)
不管是在面试还是实际开发中 volatile 都是一个应该掌握的技能。 首先来看看为什么会出现这个关键字。
下一篇
DataWorks