Java关键字volatile的实现原理(四)
简述
volatile 是轻量级的synchronized,在多线程开发中保证了共享变量的可见性。可见性就是当一个线程修改一个共享变量时,另一个线程可以读到修改的值。如果volatile变量使用恰当,它比synchronized的使用成本更低,因为它不会引起线程上下文的切换和调度。
什么是volatile
Java语言提供了一种稍弱的同步机制,即 volatile 变量,用来确保共享变量能被多线程正确的更新和读取。当把变量声明为volatile后,编译器和运行时就会认为这个变量是共享的,因此不会把该变量的操作和其他内存操作一起重排序。volatile 变量不会被缓存在寄存器或者其他处理器不可见的地方,因此在读取volatile 修饰的变量时总会返回最新的值。
volatile 的实现原理
在了解volatile 的实现原理之前,我们先看一下与其相关的CPU术语:
| 术语 | 英文名称 | 术语描述 |
|---|---|---|
| 内存屏障 | memory barriers | 一组处理器指令,用来限制对内存操作的顺序 |
| 缓冲行 | cache line | 缓存中可以分配的最小存储单位,处理器在填写缓存行时,会加载整个缓存行,需要多个主内存读周期 |
| 原子操作 | automic operations | 不可中断的一个或一系列操作 |
| 缓冲行填充 | cache line fill | 当处理器识别到从内存中读取的操作数是可以缓存的,处理器会读取整个缓存行到适当的缓存(L1,L2,L3) |
| 缓存命中 | cache hit | 处理器从缓存中读取到了需要的数据 |
| 写命中 | write hit | 当处理器将操作数写会到缓存区域时,会先检查这个缓存的内存地址是否在缓存行中,如果存在一个有效的缓存行,则处理器将这个操作数写回到缓存,而不是写到内存,这个操作被称为 写命中 |
| 写缺失 | write misses the cache | 一个有效的缓存行被写到不存在的内存区域 |
volatile 如何保证可见性
为了提高处理速度,处理器不直接和内存进行通信,而是先将系统内存的数据读到内部缓存(L1,L2,L3或其他)后再进行操作,但是操作完不知道何时会被写到内存。
如果对声明了volatile 的变量进行写操作,JVM 就会向处理器发送一条Lock前缀的指令,将这个变量所在缓存行的数据写回到系统内存。
在多核处理器下,为了保证各个处理器的缓存是一致的,就会实现缓存一致性协议,每个处理器通过嗅探在总线上传播的数据来检查自己缓存的值是否过期,当处理器发现自己缓存行对应的内存地址被修改,就会将当前处理器的缓存行设置成无效状态,当处理器对这个数据进行修改操作的时候,会重新从系统内存中把数据读到处理器缓存里。
volatile 实现原则
1、Lock 前缀的指令会引起处理器缓存回写到内存
如果访问的内存区域已经缓存在处理器内部,此时当前处理器会锁定这块内存区域的缓存并写到内存,并使用缓存一致性机制来确保修改的原子性,此操作被称为 缓存锁定,缓存一致性机制会阻止同一时间修改两个以上处理器缓存的内存区域的数据。
2、一个处理器的缓存回写到内存会导致其他处理器的缓存失效
处理器使用嗅探技术保证它的内部缓存、系统内存 和 其他处理器的缓存的数据在总线上保持一致。如果通过嗅探一个处理器来检测其他处理器打算写内存地址,而这个内存地址当前处于共享状态,那么正在嗅探的处理器将使它的缓存行无效,在下次访问相同内存地址是,强制执行缓存行填充。
volatile 的局限性
虽然volatile变量使用很方便,但也存在一些局限性。volatile变量通常用作某个操作完成、发生中断或者状态的标志。尽管volatile 变量也可以用于表示其他的状态信息,但在使用时要非常小心。例如:volatile 的语义不足以确保递增操作(count++)的原子性,除非能确保只有一个线程对变量进行写操作。
加锁机制既可以确保可见性又可以确保原子性,而volatile 变量只能确保可见性。
当满足以下所有条件时,才应该使用volatile 变量:
1、对变量的写入操作不依赖于变量的当前值,或者确保只有一个线程更新变量的值
2、该变量不会与其它变量一起作为不变性条件
3、在访问变量时不需要加锁
Java关键字volatile的实现原理(四)的更多相关文章
- java 关键字volatile
一.Java内存模型 想要理解volatile为什么能确保可见性,就要先理解Java中的内存模型是什么样的. Java内存模型规定了所有的变量都存储在主内存中.每条线程中还有自己的工作内存,线程的工作 ...
- JAVA关键字Volatile的特性
一.简述: 关键字Volatile是JAVA虚拟机提供的最轻量级的同步机制,但是它并不容易完全被正确.完整的理解,以致于许多程序员在遇到需要处理多线程数据竞争的时候一律使用synchronized来进 ...
- Java 关键字volatile的解释
volatile 关键字特征: 1.可见性,是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的.可以禁止线程的工作内存对volatile修饰的变量进行缓存,并将修改的变量立即写入主存. 2. ...
- Java关键字-volatile
关键字volatile可以说是Java虚拟机提供的最轻量级的同步机制. 一旦某个共享变量(类的成员变量.类的静态成员变量)被volatile修饰之后,那么就具备了两层语义: 1.保证了不同线程对这个变 ...
- java关键字volatile用法详解
volatile关键字想必大家都不陌生,在java 5之前有着挺大的争议,在java 5之后才逐渐被大家接受,同时作为java的关键字之一,其作用自然是不可小觑的,要知道它是java.util.con ...
- 深入汇编指令理解Java关键字volatile
volatile是什么 volatile关键字是Java提供的一种轻量级同步机制.它能够保证可见性和有序性,但是不能保证原子性 可见性 对于volatile的可见性,先看看这段代码的执行 flag默认 ...
- 关于 Java 关键字 volatile 的总结
1 什么是 volatile volatile 是 Java 的一个关键字,它提供了一种轻量级的同步机制.相比于重量级锁 synchronized,volatile 更为轻量级,因为它不会引起线程上下 ...
- Java内存模型及Java关键字 volatile的作用和使用说明
先来看看这个关键字是什么意思:volatile [ˈvɒlətaɪl] adj. 易变的,不稳定的; 从翻译上来看,volatile表示这个关键字是极易发生改变的.volatile是java语言中, ...
- Java 关键字volatile 与 synchronized 作用与区别
1,volatile 它所修饰的变量不保留拷贝,直接访问主内存中的. 在Java内存模型中,有main memory,每个线程也有自己的memory (例如寄存器).为了性能,一个线程会在自己 ...
随机推荐
- linux安装字体库(simSun为例)
在开发过程中,发现报表打印,字体和默认字体不一样.本地开发环境(windows)没问题,但是远程linux一直出现这样的问题.经过排查发现linux没有安装中文字体库宋体. linux查看当前的字体库 ...
- 3. Java开发环境的搭建:安装JDK,配置环境变量
1.安装JDK开发环境 下载网站:http://www.oracle.com/ 开始安装JDK: 修改安装目录如下: 确定之后,单击“下一步”. 注:当提示安装JRE时,可以选择不要安装. 2.配置环 ...
- javaIO——BufferedReader
今天来学习一下 java.io.BufferedReader ,从命名可以看出,跟前面学习的 StringReader 和 CharArrayReader 有些不一样,这些都是按照数据源类型命名,Bu ...
- 调用打码平台api获取验证码 (C#版)
一.打码平台很多,这里选择两个:联众和斐斐 联众开发文档: https://www.jsdati.com/docs/guide 斐斐开发文档: http://docs.fateadm.com/web/ ...
- ES6入门十:iterator迭代器
迭代模式 ES6迭代器标准化接口 迭代循环 自定义迭代器 迭代器消耗 一.迭代模式 迭代模式中,通常有一个包含某种数据集合的对象.该数据可能存在一个复杂数据结构内部,而要提供一种简单的方法能够访问数据 ...
- RobHess的SIFT代码解析步骤二
平台:win10 x64 +VS 2015专业版 +opencv-2.4.11 + gtk_-bundle_2.24.10_win32 主要参考:1.代码:RobHess的SIFT源码 2.书:王永明 ...
- Dart的List比较特殊的几个API
List里面常用的属性和方法: 常用属性: length 长度 reversed 翻转 isEmpty 是否为空 isNotEmpty 是否不为空 常用方法: add 增加 addAll 拼接数组 i ...
- 关于postgres数据库部署之后,发现不能被外机连接解决办法
数据库 部署完毕之后,用其他机器的navcat连接发现不能连接,如下报错信息 于是在数据库服务器上查询是否启动正常,端口是否正常,发现都没有问题,由于之前也遇到了mysql部署之后,不能被其他机器访问 ...
- Java&Selenium处理页面Table以及Table中随机位置的数据
一.摘要 前一段时间公司小伙伴刚刚接触自动化,遇到的一个问题,页面新创建的数据保存后,出现在table中的某个位置,并不一定是第一行还是第几行,这种情况下如何去操控它 本篇博文将介绍处理这个问题的一种 ...
- 百度人脸识别java html5
1.前端thymeleaf+h5 index.html 人脸识别+定位,用的百度sdk <!DOCTYPE html> <html xmlns="http://www ...