首页 > 作文

java 中的volatile关键字

更新时间:2023-04-04 02:33:43 阅读: 评论:0

目录
1.volatile实现可见性的原理是什么?2.演示volatile的可见性

1.volatile实现可见性的原理是什么?

volatile变量修饰的共享变量进行写操作的时候汇编代码会多出一个lock前缀指令。

在该指令下,多核处理器会引发两件事:

将当前处理器缓存行的数据写回系统内存这个写回内存的操作会使在其他cpu里缓存了该内存地址的数据无效

这里需要简单了解cpu缓存一致性问题:多核处理器环境下,每个cpu都有自己的缓存行,缓存了内存中的数据,要维护多个cpu中缓存的数据一致性,就需要解决两个问题:

一是写传播(某个cpu里的cache数据更新时,需要传交行分期播到其他cpu的cache中);二是事务的串行化执行(在某个cpu里对数据的修改,在其他cpu中看起来顺序是一样的,也就是要引入近似[锁]的概念,保证同一时刻只有一个cpu可以对数据做修改);

写传播是通过[总线嗅探]完成的:通过总线把修改数据的事件广播通知给其他所有的核心,每个cpu核心都会监听总线上的广播事件,并检查是否有相同的数据在自己的cache里面;而事务的串行化则通过[mesi协议]来完成。

mesi(modified(已修改)、exclusive(独占)、shared(共享)、ivalidated(已失效))协议中,如果要修改一个共享数据,不能直接修改,要先向其他cpu广播一个请求,把其他cpu cache中对应的数据状态改为invalidated;以后其他cpu在读取标记为invalidated的数据时,需要强制从内存中读取数据。

2.演示volatile的可见性

public class volatiledemo {    static  int flag = 1;  // 定义一个共享变量    public static void main(string[] args) {        // 两个线程,一个线程负责读取flag的值,另一个线程负责修改flag的值        new thread(){            int localflag = flag;            @override            public void run() {                while(true){                    //flag被修改后就跟localflag不一样了                    if(localflag!=flag){                        system.out.println("读到了flag修改后的值:"+ flag);                        //把读到的值赋值给本地变量                        localflag = flag;                    }        短发气质美女        }            }        }.start();        new thread(){            int localflag = flag;            @override            public void run() {                while (tru蔡琴的经典歌曲e){                    //一直对flag的值进行修改                    system.out.println("对flag的值进行修改:"+ ++localflag);                    flag = localflag;                    //休眠一秒更好地观察结果                    try {                        thread.sleep(1000);                    } catch (int北京情人节去哪玩erruptedexception e) {                        e.printstacktrace();                    }                }            }        }.start();    }}

可以看到另一个线程并不能及时读取到被修改的值。

共享变量用volatile修饰后:

public class volatiledemo {    static  volatile int flag = 1;    public static void main(string[] args) {        // 两个线程,一个线程负责读取flag的值,另一个线程负责修改flag的值        new thread(){            int localflag = flag;            @override            public void run() {                while(true){                    //flag被修改后就跟localflag不一样了                    if(localflag!=flag){                        system.out.println("读到了flag修改后的值:"+ flag);                        //把读到的值赋值给本地变量                        localflag = flag;                    }                }            }        }.start();        new thread(){            int localflag = flag;            @override            public 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关键字内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

本文发布于:2023-04-04 02:33:42,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/b5dcba8eac3452bfeeb36f0cd7e9ae3f.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:java 中的volatile关键字.doc

本文 PDF 下载地址:java 中的volatile关键字.pdf

标签:数据   线程   缓存   变量
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图