java|java 中的volatile关键字
目录
- 1.volatile实现可见性的原理是什么?
- 2.演示volatile的可见性
1.volatile实现可见性的原理是什么? 有
volatile
变量修饰的共享变量进行写操作的时候汇编代码会多出一个Lock
前缀指令。在该指令下,多核处理器会引发两件事:
- 将当前处理器缓存行的数据写回系统内存
- 这个写回内存的操作会使在其他CPU里缓存了该内存地址的数据无效
- 一是写传播(某个CPU里的cache数据更新时,需要传播到其他CPU的cache中);
- 二是事务的串行化执行(在某个CPU里对数据的修改,在其他CPU中看起来顺序是一样的,也就是要引入近似[锁]的概念,保证同一时刻只有一个CPU可以对数据做修改);
Cache
里面;而事务的串行化则通过[MESI协议]来完成。MESI
(Modified(已修改)、Exclusive
(独占)、Shared
(共享)、Ivalidated
(已失效))协议中,如果要修改一个共享数据,不能直接修改,要先向其他CPU广播一个请求,把其他CPU cache中对应的数据状态改为Invalidated
;以后其他CPU在读取标记为Invalidated
的数据时,需要强制从内存中读取数据。文章图片
2.演示volatile的可见性
public class VolatileDemo {staticint flag = 1; // 定义一个共享变量public static void main(String[] args) {// 两个线程,一个线程负责读取flag的值,另一个线程负责修改flag的值new Thread(){int localflag = flag; @Overridepublic void run() {while(true){//flag被修改后就跟localflag不一样了if(localflag!=flag){System.out.println("读到了flag修改后的值:"+ flag); //把读到的值赋值给本地变量localflag = flag; }}}}.start(); new Thread(){int localflag = flag; @Overridepublic void run() {while (true){//一直对flag的值进行修改System.out.println("对flag的值进行修改:"+ ++localflag); flag = localflag; //休眠一秒更好地观察结果try {Thread.sleep(1000); } catch (InterruptedException e) {e.printStackTrace(); }}}}.start(); }}
【java|java 中的volatile关键字】
文章图片
可以看到另一个线程并不能及时读取到被修改的值。
共享变量用volatile修饰后:
public class VolatileDemo {staticvolatile int flag = 1; public static void main(String[] args) {// 两个线程,一个线程负责读取flag的值,另一个线程负责修改flag的值new Thread(){int localflag = flag; @Overridepublic void run() {while(true){//flag被修改后就跟localflag不一样了if(localflag!=flag){System.out.println("读到了flag修改后的值:"+ flag); //把读到的值赋值给本地变量localflag = flag; }}}}.start(); new Thread(){int localflag = flag; @Overridepublic void run() {while (true){//一直对flag的值进行修改System.out.println("对flag的值进行修改:"+ ++localflag); flag = localflag; //休眠一秒更好地观察结果try {Thread.sleep(1000); } catch (InterruptedException e) {e.printStackTrace(); }}}}.start(); }}
文章图片
可以看到用
volatile
修饰后,每次另一个线程总能读取到修改后的值。到此这篇关于java 中的volatile关键字的文章就介绍到这了,更多相关volatile关键字内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- 热闹中的孤独
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- JS中的各种宽高度定义及其应用
- 我眼中的佛系经纪人
- 《魔法科高中的劣等生》第26卷(Invasion篇)发售
- Android中的AES加密-下
- 事件代理
- 放下心中的偶像包袱吧
- C语言字符函数中的isalnum()和iscntrl()你都知道吗
- Java|Java OpenCV图像处理之SIFT角点检测详解