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

菜鸡每日一面系列打卡14

每天一道面试题目 

助力小伙伴轻松拿offer

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

题目描述

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

题目分析

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

题目解答

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

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

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

    但这并不意味着,使用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关键字的一些理解,供大家参考。

 

学习 | 工作 | 分享

长按关注“有理想的菜鸡

只有你想不到,没有你学不到

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值