volatile 型变量的特殊规则
关键字 volatile 可以说是Java虚拟机提供的最轻量级的同步机制,但是它并不容易被正确地,完全地理解,以至于许多程序员都习惯不去使用它,遇到需要处理多线程数据竞争的问题时一律使用 synchronized 来进行同步。一定要弄清楚volatile 型变量的语义是什么。
当一个变量被定义成volatile 之后,它将具备两种特性,第一是保证此变量对所有线程的可见性,这里的"可见性"是指当一条线程修改了这个变量,新值对于其他线程来说是可以立即得知的。而普通变量不能做到这一点,变量值在线程间传递均需要通过主内存来完成,如:线程A修改了一个普通变量,然后向主内存进行回写,另外一条线程B在线程A回写完成了之后再从主内存进行读取操作,新变量的值才会对线程B可见。
volatile 型变量在各个线程的工作内存中不存在一致性问题(在各个线程的工作内存中volatile 变量也可以存在不一致的情况,但由于每次使用之前都要刷新,执行引擎看不到不一致的情况,因此可以认为不存在一致性的问题),但是Java里面的运算并非原子性,导致volatile 变量的运算在并发下一样是不安全的。
由于volatile 变量只能保证可见性,在不符合以下两条规则的运算场景中,我们仍然要通过加锁(使用synchronized或java.util.concurrent中的原子类)来保证原子性。
使用volatile 变量的第二个语义是禁止指令重排序优化,普通变量仅仅会保证在该方法的执行过程中所有依赖复制结果的地方都能获取正确的结果,而不能保证变量的赋值的顺序与程序代码中的执行顺一致。因为在一个线程方法执行过程中无法感知这点,这也就是Java内存模型中描述的所谓'"线程内表现为串行的语义"。
volatile 同步机制的性能要优于锁(synchronized或java.util.concurrent中的锁),但是由于虚拟机对锁实行的许多消除和优化,使得我们很难量化地说volatile 就会比synchronized快上多少。如果让volatile 自己与自己比较,则可以确定一个原则:volatile 变量读操作的性能消耗与普通变量及就没有什么差别,但是写操作可能会慢上一些,因为它需要在本地代码中插入许多内存屏障指令来保证处理器不发生乱序执行。
Java内存模型中对volatile 变量定义的特殊规则:
-
volatile变量的操作必须按read->load->use顺序,即每次在工作内存中使用变量前必须先从主内存中刷新最新的值,以保证能看到其他线程对变量的最新修改。
-
volatile变量的操作必须按assign->store->write顺序,即每次在工作内存为变量赋值之后必须将变量的值同步回主内存,以保证让其他线程能看到变量的最新修改。
-
若线程对volatile变量A的assign或者use操作先于对volatile变量B的assign或者use操作,则线程对volatile变量A的read/load或者store/write操作也必定先于对volatile变量B的read/load或者store/write操作。
分享到:
相关推荐
论坛摘下来的。
内含多种变量命名规则,对一位合格编程程序员来进,这种规则至关重要,是培养编码好的习惯。
主要是C++变量命名规则的一些常规用法。
单臂连续型变量(直接合并效应量)Meta分析,连续型变量
char型变量中能不能...不过,如果某个特殊的汉字没有被包含在unicode编码字符集中,那么,这个char型变量中就不能存储这个特殊汉字。补充说明:unicode编码占用两个字节,所以,char类型的变量也是占用两个字节。
C_C++变量命名规则, 山高谷深
养 成 良 好 的 编 程 规 范
常见的C++语言中变量名称的命名规则,基本涵盖了常用的一些变量说明
变量命名规则 下面是关于变量名(也称为标识符)的一些规则 必须以一个字母或一个下划线字符开头。后面可以使用一个字母、数字或下划线字符的序列,长度不限。 字母可以是大写或小写,大小写是不同的。也就是说,...
Bash特殊变量讲解 一些bash的特殊变量,拿来作为参考还不错
在规则包测试过程中,若要知道变量在每个规则中执行情况,变量在每个规则中值的变化情况,就可以对该变量进行“调试跟踪”。这样就可以把变量在每个规则、规则集的值赋值、变化、结果情况全部记录下来。这个变量即...
C语言变量名命名规则[整理].pdf
将Char型变量转换成Double型变量的Matlab代码
变量命名规则 数据类型 运算符 格式化输出 流程控制
变量命名还应遵守以下某条著名的命名规则: 著名的变量命名规则Camel 标记法首字母是小写的,接下来的字母都以大写字符开头。例如: 代码如下:var testValue = 0, secondValue = “hi”;Pascal 标记法首字母是大写的...
C语言变量名命名规则 一、程序风格: 1、严格采用阶梯层次组织程序代码: 各层次缩进的分格采用VC的缺省风格,即每层次缩进为4格,括号位于下一行。 要求相匹配的大括号在同一列,对继行则要求再缩进4格。例如: 2、...
C语言变量命名规则.doc
NSIS 中系统特殊路径变量基础知识 列举了脚本中(32/64位)众多常用及非常用的命令变量,帮助你轻松了解NSIS中的变量
金蝶通过变量选择单据转换规则.doc