请选择 进入手机版 | 继续访问电脑版

线程不安全之volatile关键字

[复制链接]
舞鴐雲腾 发表于 2021-1-1 17:44:27 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
文章目次



线程不安全之volatile关键字

上篇博文讲了线程不安全问题
https://editor.csdn.net/md/?articleId=111461834
可见性



  • 就是说, 在多线程的情况下,某个共享变量A被此中一个线程修改了,其他线程就会知道有一个线程修改了这个共享变量A,然后其他线程若是要使用这个共享变量,就会直接去内存中去读取整个共享变量,而不是从自己的空间中去读取这个变量A。(线程自己的内存区域中存储着这个变量A的缓存地点,当他发现有别的线程去修改变量A的时候,就会强制让自己内存区域中的这个变量A的缓存地点无效,然后去从主存中去访问这个变量A,缓存和主存的内容是一致的)
  • 被volatile申明的变量就具有可见性的性质
有序性



  • 在我们底子的明白上 Java的代码执行是顺序执行的,但是在虚拟机里代码大概会进行重排序
    1. int a = 1;  //1 int b = 1;  //2 a++;        //3 b++;        //4
    复制代码
    上面四行代码,无论先执行第三行 照旧第四行 都不会最终对a的值和b的值产生影响,所以在虚拟机执行这些代码的时候就大概进行重排序。但是如果第三行代码需要执行的时候需要消耗5ms,但第四行只需要消耗1ms,所以固然就会先执行第四行。
  • 但是在多线程内里就会大概出现问题了
    1. boolean static ready = false;int static x = 0;Thread t  = new Thread(new Runnable() {     @Override     public void run(){         if (ready) {             t++;         }      }});t.start;ready = true;  // 1System.out.println(x);         // 2
    复制代码
    如果第1和第2发生重排序的话就会发生线程不安全问题。
    但是 volatile 修饰的关键字只能让自己自己不发生重排序。也就是说我只呆在自己的位置,而且让我背面的不去前面 ,前面的不去背面,起到一个屏蔽的作用。 但是无法阻碍前面的和前面(背面的和背面的)被重排序。
分析一下单例模式

  1. public class lesson4 {    private static volatile lesson4  LS= null;    // 双重校验锁    public void getLesson() {        if (LS == null) {  // 1                     synchronized (lesson4.class) { // 2                if (LS == null) { // 3                    LS = new lesson4(); // 4                }            }// 5        }    }}
复制代码
假设有线程 A 和 线程 B 同时去执行 getLesson() 方法

  • 第一种大概就是 A B两个 线程都执行到了 第2行代码 然后去抢占锁,假设A线程抢占锁乐成,然后去执行3 4 行代码,最后执行第五行代码代码也就是释放锁之前,B线程一直就被卡在了第二行代码。但是当他获取锁之后,发现LS != null ,volatile关键字让他从内存中望见了了LS不为null,已经被new了,然后B线程就释放锁。
  • synchronized 包管了利用是原子的,也就是说当有一个线程去new LS的时候,其他线程是无法LS进行利用的,而第三行又包管了不会重复new
  • 但是抢占锁这个利用是挺泯灭cpu资源的,第1行的就是为了提高效率,若是已经new了一个LS,那木我们就可以直接判定不为null,不进去抢占锁了,淘汰了cpu资源的泯灭
  • 我们知道 new 一个对象在JVM虚拟机中可以分为四步走,第一就是类加载过程,知道这个类会泯灭多少内存空间,第二步就是开发内存空间,第三步就是在空间上创建这个对象,第四步就是把这个对象赋值给字段。 volatile 关键字包管初始化对象和对象引用的时候不会进行指令重排序。

来源:https://blog.csdn.net/shadow___h/article/details/112000485
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


专注素材教程免费分享
全国免费热线电话

18768367769

周一至周日9:00-23:00

反馈建议

27428564@qq.com 在线QQ咨询

扫描二维码关注我们

Powered by Discuz! X3.4© 2001-2013 Comsenz Inc.( 蜀ICP备2021001884号-1 )