JAVA关键字Volatile的特性
一、简述:
关键字Volatile是JAVA虚拟机提供的最轻量级的同步机制,但是它并不容易完全被正确、完整的理解,以致于许多程序员在遇到需要处理多线程数据竞争的时候一律使用synchronized来进行同步,了解volatile变量的语义对后面了解多线程操作的其他特性很有意义。
二、应用:
当一个变量被定义为volatile之后,它将具备两种特性:
1. 保证此变量对所有线程的可见性:
这里的可见性是指当一个线程修改了变量的值,新值对于其他线程来说是可以立即得知的,而普通变量不能做到这一点,普通变量的值在线程间传递需要通过主内存来完成。
volatile变量在各个线程中是一致的,但基于volatile变量的运算在并发下却不一定是安全的,参见如下案例:
public class Volatile {
public static volatile int count = 0;
public static void increaseCount() {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
};
count++;
}
public static void main(String[] args) {
for (int i = 0; i < 1000; i++) {
new Thread(new Runnable() {
@Override
public void run() {
increaseCount();
}
}).start();
}
System.out.println("count值: " + count);
}
}
预想的返回值应该是1000,但实际的返回结果值却是小于1000的值,原因在于:
利用javap发编译后得到代码清单,对应的increaseCount()对应的字节码指令如下:
public static void increaseCount();
Code :
Stack=2, Locals=0, Args_size=0
0: getstatic
3: iconst_1
4: iadd
5: putstatic
8: return
当getstatic指令把count的值取到操作栈顶是,volatile关键字保证了count在此时是正确的,但是在执行iconst_1、iadd这些指令时,其他线程可能已经把count的值加大了,而在操作栈顶的数据就变成了过期的数据,所以putstatic执行后就可能把较小的count值同步回主内存中了。
所以,由于volatile变量只能保证可见性,在不符合以下两条规则的运算场景中,仍需要通过加锁来保证原子性:
1)运算结果并不依赖变量的当前值,或者能够确保只有单一的线程修改变量值;
2)变量不需要与其他的状态变量共同参与不变约束。
2. 禁止指令重排序优化
普通的变量仅仅会保证在该方法的执行过程中所有依赖赋值结果的地方都能获取到正确的结果,而不能保证变量赋值操作的顺序与程序代码中的执行顺序一致,如下场景:
boolean flag = false;
线程A:
doSomeThing();
flag = true;
线程B:
while(!flag){
doSomeThingElse();
}
A.doSomeThing();//调用A线程的方法
如果定义flag变量时如果没有使用volatile修饰,就有可能由于指令重排序的优化,导致位于线程A中最后一句"flag = true"被提前执行,这样在线程B中调用的A的方法就有可能出现错误,使用volatile可以避免此现象的发生。
三、总结
volatile的同步性能机制要优于synchronized,但由于虚拟机对锁实行的许多消除和优化,实际上我们很难量化的认为volatile会比synchronized快多少,但volatile跟自己相比而言:volatile变量读操作的性能消耗与普通变量几乎没什么差别,但是写操作则可能慢一些,因为他需要在本地代码中插入许多内存屏障来保证处理器不发生乱序执行。
JAVA关键字Volatile的特性的更多相关文章
- Java 关键字volatile的解释
volatile 关键字特征: 1.可见性,是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的.可以禁止线程的工作内存对volatile修饰的变量进行缓存,并将修改的变量立即写入主存. 2. ...
- Java关键字-volatile
关键字volatile可以说是Java虚拟机提供的最轻量级的同步机制. 一旦某个共享变量(类的成员变量.类的静态成员变量)被volatile修饰之后,那么就具备了两层语义: 1.保证了不同线程对这个变 ...
- Java内存模型及Java关键字 volatile的作用和使用说明
先来看看这个关键字是什么意思:volatile [ˈvɒlətaɪl] adj. 易变的,不稳定的; 从翻译上来看,volatile表示这个关键字是极易发生改变的.volatile是java语言中, ...
- 关于 Java 关键字 volatile 的总结
1 什么是 volatile volatile 是 Java 的一个关键字,它提供了一种轻量级的同步机制.相比于重量级锁 synchronized,volatile 更为轻量级,因为它不会引起线程上下 ...
- java 关键字volatile
一.Java内存模型 想要理解volatile为什么能确保可见性,就要先理解Java中的内存模型是什么样的. Java内存模型规定了所有的变量都存储在主内存中.每条线程中还有自己的工作内存,线程的工作 ...
- java关键字volatile用法详解
volatile关键字想必大家都不陌生,在java 5之前有着挺大的争议,在java 5之后才逐渐被大家接受,同时作为java的关键字之一,其作用自然是不可小觑的,要知道它是java.util.con ...
- 深入汇编指令理解Java关键字volatile
volatile是什么 volatile关键字是Java提供的一种轻量级同步机制.它能够保证可见性和有序性,但是不能保证原子性 可见性 对于volatile的可见性,先看看这段代码的执行 flag默认 ...
- java关键字volatile内存语义详细分析
volatile变量自身具有下列特性. 1.可见性.对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写 入. · 2.原子性:对任意单个volatile变量的读/ ...
- Java 关键字volatile 与 synchronized 作用与区别
1,volatile 它所修饰的变量不保留拷贝,直接访问主内存中的. 在Java内存模型中,有main memory,每个线程也有自己的memory (例如寄存器).为了性能,一个线程会在自己 ...
随机推荐
- hackerrank Alex对战Fedor
任意门 为了在漫长得飞行旅途中娱乐,Alex和Fedor发明了如下的一个简单的双人游戏.游戏是: 首先, Alex画一个有权无向图.该图中可能有多重边(多重边的权值可能相同或者不同). 然后,Fedo ...
- 1492: [NOI2007]货币兑换Cash
Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券(以下 简称B券).每个持有金券的顾客都有一个自己的帐户.金券的数目可以是一个 ...
- HDU 1003 Max Sum【动态规划求最大子序列和详解 】
Max Sum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Sub ...
- Codeforces Round #345 (Div. 2)【A.模拟,B,暴力,C,STL,容斥原理】
A. Joysticks time limit per test:1 second memory limit per test:256 megabytes input:standard input o ...
- HDU--1212大数取模
大数取模问题.题目传送门:HDU1212 #include <iostream> using namespace std; char a[1010]; int main() { int b ...
- c语言实现封装、继承和多态
1. 概述 C语言是一种面向过程的程序设计语言,而C++是在C语言基础上衍生来了的面向对象的语言,实际上,很多C++实现的底层是用C语言实现的,如在Visual C++中的Interface其实就是 ...
- win7 64位安装redis 及Redis Desktop Manager使用(转载的)
写基于dapper的一套自动化程序,看到 mgravell的另一个项目,StackExchange.Redis,之前在.NET上用过一段时间Redis,不过一直是其它的驱动开发包,这个根据作者介绍,是 ...
- [国嵌攻略][179][OpenSSL加密系统]
未加密传输的安全弊端 如果在网络传输中没有加密,就是以明文传输.传输的数据可以被抓包软件直接截获,并能读取里面的数据. 加密基本原理 1.对称加密 2.非对称加密 2.1.公钥私钥 公钥和私密要配对. ...
- Yourphp系统发生错误
今天早用YP更新缓存,弹出如下错误: 随之而来的是错误信息是: [php] view plain copy [14-12-03 10:48:12] E:\wwwweb\xmwszt360\Core\L ...
- 豹哥嵌入式讲堂:ARM Cortex-M开发之文件详解(8)- 镜像文件(.bin/.hex/.s19)
大家好,我是豹哥,猎豹的豹,犀利哥的哥.今天豹哥给大家讲的是嵌入式开发里的image文件(.bin, .hex, .s19). 今天这节课是豹哥<ARM Cortex-M开发之文件详解>主 ...