面试官: 有了解过volatile关键字吗 说说看

前言

目前正在出一个Java多线程专题长期系列教程,从入门到进阶含源码解读, 篇幅会较多, 喜欢的话,给个关注❤️ ~ 本篇内容纯理论一点

概念回顾

首先我们回顾一下之前讲的基本概念:

内存可见性

「内存可见性,指的是线程之间的可见性,当一个线程修改了共享变量时,另一个线程可以读取到这个修改后的值」

重排序

为优化程序性能,对原有的指令执行顺序进行优化重新排序。重排序可能发生在多个阶段,比如编译重排序、CPU重排序等。

happens-before

遵循happens-before规则,JVM就能保证指令在多线程之间的顺序性符合执行的预期。

volatile

  • 保证变量的「内存可见性」
  • 禁止volatile变量与普通变量「重排序」

那么这个内存可见性过程是怎么样的呢❓之前也有给大家演示过具体代码,这里直接给大家总结一下:

所谓内存可见性, 当一个线程对volatile修饰的变量进行操作时,会立即将本地内存中的共享变量刷新到主内存, 同理,当进行操作时,会立即将本地内存失效,从主内存中读取共享变量的值。

在这一点上,volatile与锁具有相同的内存效果,volatile变量的写和锁的释放具有相同的内存语义,volatile变量的读和锁的获取具有相同的内存语义。

禁止重排又是怎么回事呢❓

在JSR-133之前的旧的Java内存模型中,是允许volatile变量与普通变量重排序的。想想看,如果可重排,会发生什么?

我们假设有两个线程A和B,一个被volatile修饰的变量a,一个未被修饰的普通变量b,看下边代码:

class Singleton {
    private static volatile Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if(instance == null) {
            synchronized (Singleton.class{
                if(instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

这样在多线程环境下,可以保证其安全性

结束语

本节内容可能不像之前那么好理解,比较抽象,所以本文也有不足的地方,大家自己可以多查查一些资料,综合理解, 不要去背概念。本节我们提到了锁的概念,下一节,带大家深入学习一下Java的synchronized与锁 ~

往期内容推荐

项目源码(源码已更新 欢迎star⭐️)

  • java-thread-all

  • 地址: https://github.com/qiuChengleiy/java-thread-all.git

推荐 SpringBoot & SpringCloud (源码已更新 欢迎star⭐️)


本篇文章来源于微信公众号: 程序员皮卡秋



微信扫描下方的二维码阅读本文

此作者没有提供个人介绍
最后更新于 2023-06-27