volatile的使用场景
单词解释:
乱序执行:指CPU对代码的执行顺序进行乱序优化,但保证各执行代码单元的顺序按指令顺序排列。以达到充分利用处理器的各处理单元的目的。(可以理解成:一个任务有不同的执行单元,这些单元之间有一定的执行顺序,但部分执行单元可提前工作,乱序执行就是让这部分执行单元提前一段时间执行,从而提高整体的效率,减少整体执行时间)。
保证线程安全的核心要素:原子性和可见性(线程的同步机制都是围绕这两点来保证线程的安全性);
race condition(竞争条件):当两个以上线程读写某些共享数据,而最后的结果取决于进程进行的精确时序,称为竞争条件(race condition);
可见性问题出现原因:
为了协调cpu和内存读写速度巨大差异的问题,所以有了高速缓存的出现(cpu不会每次获取数据都从内存获取,而是在高速缓存中存储有拷贝),但同时产生了可见性问题(由于cpu对内存中的对象的读取并不是原子操作,所以线程a拿到的对象并不一定是线程b写入的对象,此处有乱序执行的影响,但不止此因素)。
上一篇讲了volatile的特性,如下是volatile的使用条件:
volatile只能保证操作的可见性,但无法保证操作的原子性,所以使用条件会比synchronized苛刻,如下(必须同时满足):
1.更改不依赖于当前值,或能够确保只会在单一线程中修改变量的值,如果对变量的修改依赖于现有值,就是一个race condition操作,此时就需要使用其它方式了(比如synchronized),volatile对原子性的问题发能为力。
2.变量不需要和其他变量共同参与不变约束,比如start<end ,即使start和end都被标识为volatile,但当存在多个线程同时存在时,仍存在线程安全问题:
检查start<end是否成立, 在给start赋值之前不变式是有效的。
但是如果另外的线程在给start赋值之后给end赋值之前时检查start<end, 该不变式是无效的。
volatile的典型使用场景是作为标记使用:
public class SocketThread extends Thread {
public volatile boolean running = true;
@Override
public void run() {
while (running) {
// ...
}
}
}
------------------------------------------------------------------------------------------------------------------------------------------------
补充一篇在豆瓣上看到的文章,:
CPU与内存的中转站 ——了解CPU缓存的秘密
https://www.douban.com/note/204987800/,
其实,我觉着把“操作系统”系统学习一遍更好,不过,短期内暂时没有这本书的学习计划,往后排吧。
volatile的使用场景的更多相关文章
- 【Java线程】volatile的适用场景
http://www.ibm.com/developerworks/cn/java/j-jtp06197.html 把代码块声明为 synchronized,有两个重要后果,通常是指该代码具有 原子性 ...
- volatile的适用场景
volatile保证线程间的数据是可见的(共享的),但不保证数据同步 volatile相当于synchronized的弱实现,也就是说volatile实现了类似synchronized的语义,却又没有 ...
- JAVA锁和volatile的内存语义&volatile的使用场景
JAVA锁的内存语义 当线程释放锁时,JMM(Java Memory Model)会把该线程对应的本地内存中的共享变量刷新到主内存中. 当线程获取锁时,JMM会将该线程对应的本地内存置为无效.从而使得 ...
- Volatile的应用场景
1.当一个变量可能会被意想不到的更新时,要使用volatile来声明该变量,告诉编译器它所修饰的变量的值可能会在任何时刻被意外的更新. 2.语法 volatile int foo; int volat ...
- volatile有什么用?能否用一句话描述volatile的应用场景
volatile保证内存可见性和禁止指令重排.volatile用于多线程环境下的单次操作(单次读或者单次写).volatile关键字不能提供原子性. volatile关键字为实例域的同步访问提 ...
- volatile 有什么用?能否用一句话说明下 volatile 的应用场景?
volatile 保证内存可见性和禁止指令重排. volatile 用于多线程环境下的单次操作(单次读或者单次写).
- java volatile关键字作用及使用场景
1. volatile关键字的作用:保证了变量的可见性(visibility).被volatile关键字修饰的变量,如果值发生了变更,其他线程立马可见,避免出现脏读的现象.如以下代码片段,isShut ...
- 【并发编程】Volatile原理和使用场景解析
目录 一个简单列子 Java内存模型 缓存不一致问题 并发编程中的"三性" 使用volatile来解决共享变量可见性 volatile和指令重排(有序性) volatile和原子性 ...
- Java并发编程:volatile关键字解析
Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...
随机推荐
- Arch更新时failed to prepare transaction
error: failed to prepare transaction (could not satisfy dependencies) :: ffmpeg2.8: installing x265 ...
- AtCoder arc061C Snuke's Subway Trip
大意: 给你一张无向图,边有种类. 当你第一次/重新进入某种边时费用 + 1 在同一种边之间行走无费用. 求 1 到 n 的最小费用. 嗯...乍一看有一个很直观的想法:记录每个点的最短路的上一条边的 ...
- A1138. Postorder Traversal
Suppose that all the keys in a binary tree are distinct positive integers. Given the preorder and in ...
- 【P2303】Longge的问题
题目大意:求\[\sum\limits_{i=1}^ngcd(n,i)\] 题解:发现 gcd 中有很多是重复的,因此考虑枚举 gcd. \[\sum\limits_{i=1}^ngcd(n,i)=\ ...
- Maven初窥门径
Maven项目对象模型,可以使用一小段描述来管理项目的构建,报告和文档的软件项目管理工具. 安装 下载地址:http://maven.apache.org/download.cgi 下载解压,我将它放 ...
- 基于tensorflow的MNIST手写数字识别(二)--入门篇
http://www.jianshu.com/p/4195577585e6 基于tensorflow的MNIST手写字识别(一)--白话卷积神经网络模型 基于tensorflow的MNIST手写数字识 ...
- 将vcf文件转化为plink格式并且保持phasing状态
VCFtools can convert VCF files into formats convenient for use in other programs. One such example i ...
- 构造代码块、this关键字、静态变量、静态代码块、主函数
一.构造代码块: 作用:给对象进行初始化. 特点:对象一经运行就执行(与变量声明时赋初值同级别,此处注意 非法前向引用) 优先于构造函数的执行. 与构造函数的区别: 构造代码块是给所有对象统一初始化. ...
- 谈.Net委托与线程——创建无阻塞的异步调用(二)
了解IAsyncResult 现在我们已经了解,EndInvoke可以给我们提供传出参数与更新后的ref参数:也可以向我们导出异步函数中的异常信息.例如,我们使用BeginInvoke调用了异步函数S ...
- 「Python」6种python中执行shell命令方法
用Python调用Shell命令有如下几种方式: 第一种: os.system("The command you want"). 这个调用相当直接,且是同步进行的,程序需要阻塞并等 ...