暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

每日一面——没用过volatile关键字?感谢你参加这次面试

有理想的菜鸡 2020-05-16
135

菜鸡每日一面系列打卡14

每天一道面试题目 

助力小伙伴轻松拿offer

坚持就是胜利,我们一起努力!


题目描述

谈谈你对volatile关键字的理解。


题目分析

在Java面试中,尤其是有关多线程方面知识的考查,volatile关键字只会迟到,不会缺席。对volatile关键字的理解,不仅是对多线程编程实践的考查,更要求对程序执行过程和原理的把握。volatile是JVM提供的最轻量级的同步机制,但由于其不容易被正确、完整的理解,在实际工作中,很多程序员都会绕道而行。因此,在面试过程中也很容易载跟头。不仅如此,全面了解volatile关键字,对理解多线程操作很有帮助。接下来,随菜鸡一起去看看吧。


题目解答

开宗明义,volatile关键字的作用主要有两个:可见性与禁止指令重排序优化。但仅仅这样回答显然不能满足面试官的要求,还需要阐述个人理解和一些细节上的说明


  • 可见性,保证被volatile关键字修饰的变量(以下简称volatile变量)对所有线程可见。从逻辑上看,volatile变量对所有线程是立即可见的,也就是说,对volatile变量的写操作会立刻反映到其他线程当中。


    为什么强调是从逻辑上看呢?因为,从物理存储角度看,各个线程的工作内存中volatile变量可以不一致,但每次使用之前都会进行刷新,因此,逻辑上是一致的。volatile的特殊规则保证了新值能立即同步到主内存,并且storewrite操作是连续的,每次使用前立即从主内存刷新,并且readload操作是连续的。

    但这并不意味着,使用volatile变量能保证线程安全。众所周知(其实也不一定),Java中的运算操作符并非原子操作,因此,volatile变量的运算并不是线程安全的。最常见的例子便是形如i++的自增运算。

    public class IncreaseTest {


        public static volatile int i = 0;
        
        // 非线程安全,因为自增运算不是原子操作
        public static void increase() {
            i++;    
        }
        
    }

            

    • 禁止指令重排序优化,防止机器级别的指令重排序优化造成并发编程中的错误。什么是指令重排序呢?指令重排序就是处理器在保证程序能得出正确的执行结果的前提下,允许指令执行顺序的改变。这是基于优化提高效率的考虑。而在并发编程情况下,这种优化很容易是自作聪明的表现,导致一系列难以排查的问题。在《深入理解Java虚拟机》一书中,周志明老师用单例懒汉式实现的汇编代码进行了举例,说明了volatile关键字通过在指令中添加内存屏障的方式禁止了指令重排序,菜鸡在这里要说明两点:

            

      • volatile关键字主要是为了在instance变量被初始化为Singleton实例时,避免指令重排序导致的多线程不能正确处理instance变量,而由第一条可知,由于volatile的可见性,在instance变量初始化完成之后,立刻反映到其他线程当中,也就可以一定程度上避免新加入的线程对锁的竞争。

      • 书中对于单例的懒汉式实现出现了一些小失误,并未给出私有的构造方法,菜鸡对这段代码进行了补全如下。

                

      public class Singleton {


          private volatile static Singleton instance;
          
          // 私有构造方法
          private Singleton() {}
          
          public static Singleton getInstance() {
              if (instance == null) {
                  synchronized (Singleton.class) {
                      if (instance == null) {
                          instance = new Singleton();
                      }
                  }
              }
              return instance;
          }
          
      }

              

      以上便是菜鸡关于volatile关键字的一些理解,供大家参考。


      其他说明

      由于微信公众号的页面模板功能的限制,一个页面模板仅支持保存30篇文章,由于每日一题系列更新已经超过了30篇,因此,菜鸡将其全部归类到每日一题专辑中,在每日一题栏目中仅保存最近更新的30篇,需要翻看历史文章的,可以点击文章顶部的专辑进行查看,其余栏目也可采用该方式查看。如下图所示👇。




      学习 | 工作 | 分享

      👆长按关注“有理想的菜鸡

      只有你想不到,没有你学不到
      文章转载自有理想的菜鸡,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

      评论