由单例模式学到:volatile关键字
MSDN上说:
volatile 关键字指示一个字段可以由多个同时执行的线程修改。 声明为 volatile 的字段不受编译器优化的限制。 这样可以确保该字段在任何时间呈现的都是最新的值。
volatile 关键字可应用于以下类型的字段:
引用类型。
指针类型(在不安全的上下文中)。 请注意,虽然指针本身可以是可变的,但是它指向的对象不能是可变的。 换句话说,您无法声明“指向可变对象的指针”。
类型,如 sbyte、byte、short、ushort、int、uint、char、float 和 bool。
具有以下基类型之一的枚举类型:byte、sbyte、short、ushort、int 或 uint。
已知为引用类型的泛型类型参数。
可变关键字仅可应用于类或结构字段。 不能将局部变量声明为 volatile。
网上看到一篇文章说:
volatile关键字仅应用于类或结构字段,用于通知编译器,将有多个线程访问该字段,因此它不应当对此成员的状态做任何优化,这样可以确保该字段在任何时间呈现的都是最新的值。
不是所有的类型都可以被定义为volatile字段,只有以下类型才可被定义为volatile:
引用类型。
指针类型(在不安全的上下文中)。
整型,如 sbyte、byte、short、ushort、int、uint、char、float 和 bool。
具有整数基类型的枚举类型。
已知为引用类型的泛型类型参数。
IntPtr 和 UIntPtr。
注意观察一下,就能发现只有值或引用的位数不超过本机整型值的位数(在32位系统中,为4个字节)的类型才能成为volatile。为什么会这样呢?我的理解是:编译器之所以保障volatile字段在多线程情况下总是获取到最新值,最重要的一点是volatile字段操作的原子性,即编译后的本地代码只用一条机器指令就能对volatile字段赋值了。如何保证操作的原子性呢?32位系统中,对任何数据操作都是以4字节为基础,自然一条机器指定就能搞定执行一个小于4字节的赋值操作。但如果字段占用内存大于4个字节,那生成赋值语句的机器指令肯定大于一条,这样在多线程的上下文切换中,有可能刚刚赋值到一半,就被切换到其他线程了。这样,便无法保障volatile字段在多线程环境下总是呈现一个完整的、合法的最新值了。
总结:volatile关键字的目的就是在多线程访问该字段时,保证任何时间呈现的都是最新的值!
由单例模式学到:volatile关键字的更多相关文章
- 单例模式中的volatile关键字
在之前学习了单例模式在多线程下的设计,疑惑为何要加volatile关键字.加与不加有什么区别呢?这里我们就来研究一下.单例模式的设计可以参考个人总结的这篇文章 背景:在早期的JVM中,synchr ...
- 你真的了解 volatile 关键字吗?
今天,让我们一起来探讨 Java 并发编程中的知识点:volatile 关键字 本文主要从以下三点讲解 volatile 关键字: volatile 关键字是什么? volatile 关键字能解决什么 ...
- Java单例模式和volatile关键字
单例模式是最简单的设计模式,实现也非常"简单".一直以为我写没有问题,直到被 Coverity 打脸. 1. 暴露问题 前段时间,有段代码被 Coverity 警告了,简化一下代码 ...
- 双重检验的单例模式,为什么要用volatile关键字
双重检验的单例模式是比较推荐的单例写法,在该代码中的单例对象的是用volatile关键字修饰的.这时就产生的一个疑问,为什么需要volatile来修饰呢?上网查看多个博客,下面简单通俗分析一下当中的原 ...
- 对Java单例模式 volatile关键字作用的理解
单例模式是程序设计中经常用到的,简单便捷的设计模式,也是很多程序猿对设计模式入门的第一节课.其中最经典的一种写法是: class Singleton { private volatile static ...
- 双重检查锁单例模式为什么要用volatile关键字?
前言 从Java内存模型出发,结合并发编程中的原子性.可见性.有序性三个角度分析volatile所起的作用,并从汇编角度大致说了volatile的原理,说明了该关键字的应用场景:在这补充一点,分析下v ...
- Volatile关键字&&DCL单例模式,volatile 和 synchronized 的区别
Volatile 英文翻译:易变的.可变的.不稳定的. 一.volatile 定义及用法 多个线程的工作内存彼此独立,互不可见,线程启动的时候,虚拟机为每个内存分配一块工作内存,不仅包含了线程内部定义 ...
- 从简单示例看对象的创建过程, 为什么双重检查的单例模式,分析Volatile关键字不能少
编译指令 :javac Test.java 反编译指令: javap -v Test 代码 public class ObjectTest { int m = 8; public static voi ...
- 单例模式中volatile关键字的作用
背景&问题 在早期的JVM中,synchronized存在巨大的性能开销.因此,有人想出了一个"聪明"的技巧:双重检查锁定(Double-Checked Locking). ...
随机推荐
- MySQL 用户管理——权限表
权限表 权限表存放在mysql数据库中 user表结构 用户列:Host.User.Password 权限列:*priv 资源控制列:max* 安全列:其余 db表 存储了用户对某个数据库的操作权 ...
- [转载]git 忽略某些文件
项目中经常会生成一些Git系统不需要追踪(track)的文件.典型的是在编译生成过程中 产生的文件或是编程器生成的临时备份文件.当然,你不追踪(track)这些文件,可以 平时不用"git ...
- android之TabHost(上)
首先建立文件res/layout/tab.xml 代码如下: <?xml version="1.0" encoding="utf-8"?> < ...
- HDU 2089 数位dp入门
开始学习数位dp...一道昨天看过代码思想的题今天打了近两个小时..最后还是看了别人的代码找bug...(丢丢) 传说院赛要取消 ? ... 这么菜不出去丢人也好吧~ #include<stdi ...
- jpush极光推送知识点总结
1.jpushClient.sendPush(pushpayLoad):是发送推送的主要方法 2.pushpayload是具体推送消息.推送对象范围的封装 3.jpushClient.sendPush ...
- Linux提示no crontab for root的解决办法
Linux提示no crontab for root的解决办法 安装crontab:yum install crontabs 说明:/sbin/service crond start //启动服务/s ...
- JNDI学习总结(一)——JNDI数据源的配置
一.数据源的由来 在Java开发中,使用JDBC操作数据库的四个步骤如下: ①加载数据库驱动程序(Class.forName("数据库驱动类");) ②连接数据库(Connec ...
- 纯CSS制作三角(转)
原原文地址:http://www.w3cplus.com/code/303.html 原文地址:http://blog.csdn.net/dyllove98/article/details/89670 ...
- 20145317彭垚 《Java程序设计》第8周学习总结
20145317彭垚 <Java程序设计>第8周学习总结 教材学习内容总结 第十四章 1.NIO的定义 InputStream.OutputStream的输入输出,基本上是以字节为单位进行 ...
- 初学Java语法(笔记)
2015-12-30