文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java中volatile关键字实现原理

2023-05-31 11:38

关注

前言

我们知道volatile关键字的作用是保证变量在多线程之间的可见性,它是java.util.concurrent包的核心,没有volatile就没有这么多的并发类给我们使用。

本文详细解读一下volatile关键字如何保证变量在多线程之间的可见性,在此之前,有必要讲解一下CPU缓存的相关知识,掌握这部分知识一定会让我们更好地理解volatile的原理,从而更好、更正确地地使用volatile关键字。

CPU缓存

CPU缓存的出现主要是为了解决CPU运算速度与内存读写速度不匹配的矛盾,因为CPU运算速度要比内存读写速度快得多,举个例子:

这种访问速度的显著差异,导致CPU可能会花费很长时间等待数据到来或把数据写入内存。

基于此,现在CPU大多数情况下读写都不会直接访问内存(CPU都没有连接到内存的管脚),取而代之的是CPU缓存,CPU缓存是位于CPU与内存之间的临时存储器,它的容量比内存小得多但是交换速度却比内存快得多。而缓存中的数据是内存中的一小部分数据,但这一小部分是短时间内CPU即将访问的,当CPU调用大量数据时,就可先从缓存中读取,从而加快读取速度。

按照读取顺序与CPU结合的紧密程度,CPU缓存可分为:

每一级缓存中所存储的数据全部都是下一级缓存中的一部分,这三种缓存的技术难度和制造成本是相对递减的,所以其容量也相对递增。

当CPU要读取一个数据时,首先从一级缓存中查找,如果没有再从二级缓存中查找,如果还是没有再从三级缓存中或内存中查找。一般来说每级缓存的命中率大概都有80%左右,也就是说全部数据量的80%都可以在一级缓存中找到,只剩下20%的总数据量才需要从二级缓存、三级缓存或内存中读取。

使用CPU缓存带来的问题

用一张图表示一下CPU-->CPU缓存-->主内存数据读取之间的关系:

Java中volatile关键字实现原理

当系统运行时,CPU执行计算的过程如下:

  1. 程序以及数据被加载到主内存
  2. 指令和数据被加载到CPU缓存
  3. CPU执行指令,把结果写到高速缓存
  4. 高速缓存中的数据写回主内存

如果服务器是单核CPU,那么这些步骤不会有任何的问题,但是如果服务器是多核CPU,那么问题来了,以Intel Core i7处理器的高速缓存概念模型为例(图片摘自《深入理解计算机系统》):

Java中volatile关键字实现原理

试想下面一种情况:

  1. 核0读取了一个字节,根据局部性原理,它相邻的字节同样被被读入核0的缓存
  2. 核3做了上面同样的工作,这样核0与核3的缓存拥有同样的数据
  3. 核0修改了那个字节,被修改后,那个字节被写回核0的缓存,但是该信息并没有写回主存
  4. 核3访问该字节,由于核0并未将数据写回主存,数据不同步

为了解决这个问题,CPU制造商制定了一个规则:当一个CPU修改缓存中的字节时,服务器中其他CPU会被通知,它们的缓存将视为无效。于是,在上面的情况下,核3发现自己的缓存中数据已无效,核0将立即把自己的数据写回主存,然后核3重新读取该数据。

可以看出,缓存在多核CPU的使用情况下会有一些性能的缺失。

反汇编Java字节码,查看汇编层面对volatile关键字做了什么

有了上面的理论基础,我们可以研究volatile关键字到底是如何实现的。首先写一段简单的代码:

public class LazySingleton {  private static volatile LazySingleton instance = null;  public static LazySingleton getInstance() {    if (instance == null) {      instance = new LazySingleton();    }    return instance;  }  public static void main(String[] args) {    LazySingleton.getInstance();  }}

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 资料下载
  • 历年真题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯