[读书笔记]java中的volatile关键词
以下内容大多来自周志明的《深入理解Java虚拟机》。
当一个变量被volatile修饰后,它将具备两种特性:
1. 保证此变量对所有线程的可见性,这里的“可见性”是指当一条线程修改了这个变量的值,新值对于其他线程来说是可以立即得知的。而普通变量不能做到这一点,普通变量的值在线程间传递均需要通过主内容来完成,例如,线程A修改了一个普通变量的值,然后向主内容进行回写,另外一条线程B在线程A回写完成之后再从主内存进行读取操作,新变量值才会对线程B可见。
volatile变量在各个线程的工作内存中不存在一致性问题(在各个线程的工作内存中,volatile变量也可以存在不一致的情况,但由于每次使用之前都要先刷新,执行引擎看不到不一致的情况,因此可以认为不存在一致性问题),但是java里面的运算并非原子操作,导致volatile变量的运算在并发下一样是不安全的,看下面代码:
public static volatile int race = 0; public static void increase() {
race++;
} private static final int ThreadsCnt = 20; public static void main(String[] args) {
Thread[] threads = new Thread[ThreadsCnt];
for (int i = 0; i < ThreadsCnt; i++) {
threads[i] = new Thread(new Runnable() {
@Override
public void run() {
for (int j = 0; j < 10000; j++) {
increase();
}
}
});
threads[i].start();
} while (Thread.activeCount() > 1) {
Thread.yield();
}
System.out.println(race);
}
20个线程,每个线程对race进行1000次运算,但是结果却不是20000,每次运行的结果都不同。
由于volatile变量只能保证可见性,在不符合一下两条规则的运算场景中,我们仍然需要通过加锁(如synchronized)来保证原子性。
a. 运算结果不依赖变量的当前值,或者能够确保只有单一的线程修改变量的值。
b. 变量不需要与其他的状态变量共同参与不变约束。
volatile比较合适的使用场景:
volatile boolean shutDownStatus;
public voit shutDown()
{
shutDownStatus=true;
}
public void work()
{
while(!shutDownStatus)
{
//do something
}
}
2. 第二个语义:禁止指令重排序优化,普通的变量仅仅会保证在该方法的执行过程中所有依赖复制结果的地方都能获取到正确的结果,而不能保证变量赋值操作的顺序与程序代码中的执行顺序一致。
总结:volatile是轻量级的同步机制,效率可能会比synchronized高一点,但是也有较大的区别:
volatile本质是在告诉jvm当前变量在寄存器中的值是不确定的,需要从主存中读取,synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住.
volatile仅能使用在变量级别,synchronized则可以使用在变量,方法.
volatile仅能实现变量的修改可见性,但不具备原子特性,而synchronized则可以保证变量的修改可见性和原子性.
volatile不会造成线程的阻塞,而synchronized可能会造成线程的阻塞.
volatile标记的变量不会被编译器优化,而synchronized标记的变量可以被编译器优化.
volatile参考资料:
http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html
http://blog.csdn.net/fanaticism1/article/details/9966163
[读书笔记]java中的volatile关键词的更多相关文章
- [读书笔记]java中的类加载器
以下内容大多来自周志明的<深入理解Java虚拟机>. 类加载器是java的一项创新,也是java流行的重要原因之一,它最初是为了满足java applet的需求而开发出来. 什么是appl ...
- 《深入了解java虚拟机》高效并发读书笔记——Java内存模型,线程,线程安全 与锁优化
<深入了解java虚拟机>高效并发读书笔记--Java内存模型,线程,线程安全 与锁优化 本文主要参考<深入了解java虚拟机>高效并发章节 关于锁升级,偏向锁,轻量级锁参考& ...
- java中的Volatile关键字使用
文章目录 什么时候使用volatile Happens-Before java中的Volatile关键字使用 在本文中,我们会介绍java中的一个关键字volatile. volatile的中文意思是 ...
- java中的volatile关键字
java中的volatile关键字 一个变量被声明为volatile类型,表示这个变量可能随时被其他线程改变,所以不能把它cache到线程内存(如寄存器)中. 一般情况下volatile不能代替syn ...
- Java中的volatile关键字的功能
Java中的volatile关键字的功能 volatile是java中的一个类型修饰符.它是被设计用来修饰被不同线程访问和修改的变量.如果不加入volatile,基本上会导致这样的结果:要么无法编写多 ...
- 深入理解Java中的volatile关键字
在再有人问你Java内存模型是什么,就把这篇文章发给他中我们曾经介绍过,Java语言为了解决并发编程中存在的原子性.可见性和有序性问题,提供了一系列和并发处理相关的关键字,比如synchronized ...
- 一定要你明白Java中的volatile
今天Tony来和大家聊聊Java中关键字volatile. 字节码 首先volatile int a = 3;和int a = 3;, 加不加volatile关键字,最终生成的字节码都一样的.有兴趣的 ...
- 《大型网站系统与Java中间件》读书笔记 (中)
前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 回顾上一篇: <大型网站系统与Java中间件& ...
- Java编程思想—读书笔记(更新中)
第1章 对象导论 1.4 被隐藏的具体实现 访问控制的原因: 让客户端程序员无法触及他们不应该触及的部分(不是用户解决特定问题所需的接口的一部分) 允许库设计者可以改变类内容的工作方式而不用担心会影响 ...
随机推荐
- 基于内存,redis,mysql的高速游戏数据服务器设计架构
转载请注明出处,欢迎大家批评指正 1.数据服务器详细设计 数据服务器在设计上采用三个层次的数据同步,实现玩家数据的高速获取和修改. 数据层次上分为:内存数据,redis数据,mysql数据 设计目的: ...
- Codeforces Round #384 (Div. 2) 解题报告
这场CF水题都非常的水,D题如果对树.DFS相关比较熟练的话也不难.比赛时前三题很快就过了,可是因为毕竟经验还是太少,D题就卡住了.比赛之后A题还因为没理解对题意fst了--(为什么这次就没人来hac ...
- curl get
//Get方式实现 //初始化 $ch = curl_init(); //设置选项,包括URL curl_setopt($ch, CURLOPT_URL, "http://www.jb51. ...
- List<T>的对比
对于类型的对比,linq原来的对比是区分不了的. 对两个list进行查询交集方法.交集,并集的函数是直接用Linq的,这里不再写. List<T> intersectList = quer ...
- Tomcat配置错误导致Quartz执行两次问题
以下基于tomcat服务器 我们通常将域名映射到指定服务器的端口上,以通过域名直接访问服务,如http://www.abc.com域名已绑定到本机的80端口,项目名wechat,则直接访问http:/ ...
- JavaScript 基础知识之对比记忆学习
1. alter修改(易写混),alert警告 alert 函数语法:alert(str);str字符串用单引号或双引号隔开 2.标识符和关键字 标识符:由不以数字开头的字母.数字.下划线.$组成. ...
- string的实现
面试常常用到string类的实现,自己总结了一下: #pragma once #include <iostream> #include <cassert> #include & ...
- Y+的查看及FLUENT壁面函数的选择
y+的查看 其实,我们关心的应该是壁面y+值.那么我们看云图的话,是可以直接看到的,但是个人感觉,如果case大的话,也不是很方便.此外,你要是看云图的话,要用filled的方式,而且把node va ...
- Git忽略规则及.gitignore规则不生效的解决办法
在git中如果想忽略掉某个文件,不让这个文件提交到版本库中,可以使用修改根目录中 .gitignore 文件的方法(如无,则需自己手工建立此文件).这个文件每一行保存了一个匹配的规则例如: # 此为注 ...
- CheckBoxList控件获取多选择,需要遍历
CheckBoxList控件获取多选择,需要遍历,环境:vs2008 在页面上添加CheckBoxList控件,输入项值 a,b,c,d.然后添加按钮 Button2确定,如何获取CheckBoxLi ...