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 (例如寄存器).为了性能,一个线程会在自己 ...
随机推荐
- Javascript中的事件二
<!------------------示例代码一---------------------><!DOCTYPE html PUBLIC "-//W3C//DTD XHTM ...
- Django多对多
表名小写+_set() 得到的是一个QuertSet集合,她的后面可以跟 .add() .remove() .update() .clear() models.py 文件 # 学生表 ...
- 10 TCP限流技术
TCP限流是因为让接收方充分接受完消息,保证数据安全,不会丢失 一.窗口机制介绍 发送端和接收端都拥有一个窗口,当发送端发送数据时,落进窗口的数据被发送,当接受端接受数据时,落进接收端窗口的数据将会被 ...
- Delphi 线程的同步
- MySQL开启binlog无法启动ct 10 21:27:31 postfix/pickup[4801]: warning: 6BD991A0039: message has been queue
1 详细异常 ct 10 21:27:31 postfix/pickup[4801]: warning: 6BD991A0039: message has been queue Oct 10 21:2 ...
- Django—处理流程
用户通过浏览器发送请求 请求到达request中间件,中间件对request请求做预处理或者直接返回response 若未返回response,会到达urlconf路由,找到对应视图函数 视图函数做相 ...
- linux firewall指令
CentOS7中firewall防火墙详解和配置,.xml服务配置详解修改防火墙配置文件之前,需要对之前防火墙做好备份 重启防火墙后,需要确认防火墙状态和防火墙规则是否加载,若重启失败或规则加载失败, ...
- VMware无法连接MKS:套接字连接尝试次数太多解决
粘贴自:https://jingyan.baidu.com/article/425e69e61eb578be15fc16ae.html VMware在开启虚拟机的时候,突然弹出[无法连接MKS:套接字 ...
- Spark(一)wordcount
Spark(一)wordcount 一.新建一个scala项目 在maven中导入 <!-- https://mvnrepository.com/artifact/org.apache.spar ...
- C# 接口的作用浅谈举例(转)
转:http://blog.csdn.net/liuqinghui1990/article/details/77171051 我初次接触接口(Interface),对接口的作用有点迷茫,C#接口中包含 ...