微信公众号:你好面试官
这里没有碎片化的知识,只有完整的知识体系。
专注于系统全面的知识点讲解,面试题目解析;
如果你觉得文章对你有帮助,欢迎关注、分享、赞赏

###前言
二蛋几天没有收到面试通知,以为自己已经凉凉,没想到此时再次接到了面试邀请,于是在一个风和日丽的下午,二蛋如约坐在了面试官对面,开始了今天的面试。

面试官:小伙子,咱也不用继续介绍了,你也来了几次了,这次咱就开门见山吧。

正文

今天开始Java内存模型、并发编程相关的内容讲解。这一部分知识的重要性不必再过多强调,这是从入门级别到进阶过程中必须掌握的东西,几乎所有的Java中高级岗位都会要求Java并发、内存模型、虚拟机相关的技能,虚拟机相关的内容会在下一个系列继续讲解。

详细介绍下volatile?

  • 概念
    volatile是一个Java关键字,主要用于并发编程模块中,它是一个轻量级的synchronized,主要作用是在并发编程中保证共享变量的可见性。

    可见性是指当一个线程修改贡献变量时,其他线程能够感知到变量的变化。
    由于使用volatile不会引起线程的上下文切换和调度,所以开销较小,与synchronized相比使用成本更低,更加轻量。

  • volatile的底层原理
    用volatile修饰的变量进行写操作时,会多出一些汇编代码,是以 lock为前缀的汇编指令,这个指令会有以下两种效果:

    1. 将当前处理器缓存行的数据写回到系统内存。
    2. 这个写回内存的操作会使在其他CPU里缓存了该内存地址的数据无效。


每个线程使用一个变量都会从主内存中读取变量,然后缓存到自己的本地内存中,此时如果其他线程修改了当前变量的值,不会立即写回到主内存,即使写回到主内存,已经缓存了变量的线程不会感知到变量变化,所以也不会立即更新,就导致其他线程中的变量值不是最新的。如上图,ABC都缓存了X的值为10,而A线程将X值改为20,且不会立即写回到主内存,即使写回到主内存,BC线程下次使用X变量时,依然从自己的缓存中读取,所以对BC线程来说,X依然为10.

由于上边(1)的操作,只要变量值发生了变化,就会立即将新值写回到主内存,从而保证主内存中的变量值是最新的,同时,由于(2)的操作,其他线程缓存的此变量值无效,当其他线程下次需要用到此变量值的时候,就必须重新从主内存中读取,所以保证了变量的值是最新值。

使用volatile修饰的变量,由于多了上边两个步骤,就会保证任何一个线程修改了变量的值,其他线程都能立即感知到。

  • 如何让其他线程缓存的地址失效?
    在多处理器下,为了保证各个处理器的缓存是一致的,就会实现缓存一致性协议,每个处理器通过嗅探在总线.上传播的数据来检查自己缓存的值是不是过期了,当处理器发现自己缓存行对应的内存地址被修改,就会将当前处理器的缓存行设置成无效状态,当处理器对这个数据进行修改操作的时候,会重新从系统内存中把数据读到处理器缓存里。

这一块知识需要与操作系统的相关知识联系起来,搞清楚内存与缓存之间的关系以及缓存一致性协议等等。

####多处理器如何实现原子操作?
原子的意思是不能再进行分割的粒子,我们知道在化学中,原子是最小粒子。
原子操作在这里是指不可中断的一个或者一系列操作。

不同的处理器的实现方式可能不同,这里大概讲一下实现的原理:
首先处理器会自动保证基本的内存操作的原子性。处理器保证从系统内存中读取或者写入一个字节是原子的,意思是当一个处理器读取-一个字节时,其他处理器不能访问这个字节的内存地址。但是复杂的内存操作处理器是不能自动保证其原子性的,比如跨总线宽度、跨多个缓存行和跨页表的访问。但是,处理器提供总线锁定和缓存锁定两个机制来保证复杂内存操作的原子性。

  1. 使用总线锁保证原子性
    第一个机制是通过总线锁保证原子性。如果多个处理器同时对共享变量进行读改写操作,那么共享变量就会被多个处理器同时进行操作,这样读改写操作就不是原子的,操作完之后共享变量的值会和期望的不一致。
    原因可能是多个处理器同时从各自的缓存中读取变量i,分别进行加1操作,然后分别写入 系统内存中。那么,想要保证读改写共享变量的操作是原子的,就必须保证CPU1读改写共享 变量的时候,CPU2不能操作缓存了该共享变量内存地址的缓存。
    处理器使用总线锁就是来解决这个问题的。所谓总线锁就是使用处理器提供的一个 LOCK#信号,当一个处理器在总线上输出此信号时,其他处理器的请求将被阻塞住,那么该 处理器可以独占共享内存。

  2. 使用缓存锁保证原子性
    在同一时刻,我们只需保证对某个内存地址的操作是原子性即可,但总线锁定把CPU和内存之间的通信锁住了,这使得锁定期间,其他处理器不能操作其他内存地址的数据,所以总线锁定的开销比较大,目前处理器在某些场合下 使用缓存锁定代替总线锁定来进行优化。
    频繁使用的内存会缓存在处理器的L1、L2和L3高速缓存里,那么原子操作就可以直接在 处理器内部缓存中进行,并不需要声明总线锁。所谓“缓存锁定”是指内存区域如果被缓存在处理器的缓存 行中,并且在Lock操作期间被锁定,那么当它执行锁操作回写到内存时,处理器不在总线上声 言LOCK#信号,而是修改内部的内存地址,并允许它的缓存一致性机制来保证操作的原子 性,因为缓存一致性机制会阻止同时修改由两个以上处理器缓存的内存区域数据,当其他处 理器回写已被锁定的缓存行的数据时,会使缓存行无效。

有两种情况下处理器不会使用缓存锁定:

  1. 当操作的数据不能被缓存在处理器内部,或操作的数据跨多个缓存行 (cache line)时,则处理器会调用总线锁定。
  2. 有些处理器不支持缓存锁定。对于Intel 486和Pentium处理器,就算锁定的 内存区域在处理器的缓存行中也会调用总线锁定。

以上两个机制,可以通过处理器提供的Lock前缀的指令来实现。

面试官:嗯,今天的面试就到这里吧,回去好好准备下一次面试吧。



这里没有碎片化的知识,只有完整的知识体系。
专注于系统全面的知识点讲解,面试题目解析;
如果你觉得文章对你有帮助,欢迎关注、分享、赞赏

【你好面试官】008 Java内存模型指volatile底层原理详解、多处理器原子操作实现原理相关推荐

  1. 写屏障是什么_面试官为什么问内存模型总离不开final关键字,该如何应对?

    Java 语言的每个关键字都设计的很巧妙,金雕玉琢,只有深度钻研其中,才知其中懊悔,本文带领大家一起深入理解 Java 内存模型之 final. 加我微信好友的不要着急,手机没电了,等我借个充电器之后 ...

  2. Java内存模型、volatile、原子性、可见性、有序性、happens-before原则

    目录 1.硬件的效率与一致性: 缓存一致性(Cache Coherence) 2.Java内存模型 2.1主内存与工作内存 2.2内存间的交互 2.3 volatile型变量的特殊规则 2.3.1 保 ...

  3. Java JVM内存模型(运行时数据区域)详解

    详细介绍了JVM运行时数据区域,包括方法区.堆空间.栈空间.本地方法栈.程序计数器.常量池.直接内存.字面量.符号引用.直接引用. Java程序在运行时,需要在内存中的分配空间.为了提高运算效率,ja ...

  4. 内存位置访问无效_万字长文——java内存模型之volatile深入解读

    在阅读本文前,请思考以下的面试题? volatile是什么? volatile的特性 volatile是如何保证可见性的? volatile是如何保证有序性的? volatile可以保证原子性吗? 使 ...

  5. java内存模型与volatile变量与Atomic的compareAndSet

    java分主内存和工作内存, 主内存是线程共享的, 工作内存是每个线程独有的. java对主内存的操作是通过工作内存间接完成的: 先拷贝主内存变量值到工作内存, 在工作内存操作这个变量的副本, 完成后 ...

  6. 【中级02】Java Class字节码文件底层逻辑详解

    Java的class文件是什么 Class文件是jvm认识的一种字节码文件,里面的地址都是逻辑的地址.最后需要运行在操作系统中,操作系统只能识别真实的物理地址.此时需要动态链接(这个过程就是将逻辑地址 ...

  7. android中okhttp原理详解,Android中okhttp原理详解-极度针对面试篇

    一.okhttp工做的大体流程 1.一.总体流程 (1).当咱们经过OkhttpClient创立一个Call,并发起同步或者异步请求时: (2).okhttp会经过Dispatcher对咱们全部的Re ...

  8. 【JVM】第四章 Java内存模型

    第四章 Java内存模型 文章目录 第四章 Java内存模型 一.物理机的并发问题 1.硬件的效率问题 2.缓存一致性问题 3.代码乱序执行优化问题 二.Java 内存模型 1.概念 2.Java 内 ...

  9. Java内存模型深度剖析

    作者:Hollis,阿里资深攻城狮 来自:Hollis 为什么要有内存模型 在介绍Java内存模型之前,先来看一下到底什么是计算机内存模型,然后再来看Java内存模型在计算机内存模型的基础上做了哪些事 ...

最新文章

  1. Linux C中strcpy , strncpy , strlcpy 的区别
  2. OCR光学字符识别方法汇总(附开源代码)
  3. Oracle中的Union、Union All、Intersect、Minus 使用用法区别
  4. notepad运行python为啥与pycharm运行的结果不一样_零基础初学Python,需要装什么软件?...
  5. CSS3动画详解(图文教程)
  6. Two Merged Sequences(CF 1144 G)
  7. java输出栈的弹出序列_剑指offer:栈的压入、弹出序列(Java)
  8. 【分享】WeX5的正确打开方式(5)——绑定机制
  9. shell中日期的使用当前日期的加减
  10. CentOS6.5升级内核到3.10.28
  11. 高德天气 php,天气查询-API文档-开发指南-Web服务 API | 高德地图API
  12. python与vb可以互换吗_VB6+Python混合编程(COM组件)(转)
  13. springboot 集成 jwt+oauth+springsecurity 实现单点登录,feign远程调用,eruka注册中心,seata分布式事务配置
  14. 内网计算机可以使用键盘,如何在同一个局域网里一套键盘鼠标操作多台电脑?...
  15. 解决家庭版win10、win8没有远程桌面选项
  16. win10系统无法登录ftp服务器失败,Win10系统下ftp连接失败提示“连接已超时”如何解决?...
  17. 2007年中国网络游戏市场分析及投资咨询报告(上下卷)
  18. 网站在多IE版本兼容性测试工具IETester的使用方法
  19. Excel中IFs函数如何输出不满足条件下的内容
  20. 电脑无法搜索到蓝牙耳机解决办法

热门文章

  1. cass简码在内外业的应用与关联
  2. IP68遥测终端机(井下遥测终端机)
  3. android开发蓝牙传输图片,如何发送/接收文本和图片通过蓝牙android到另一个android手机...
  4. JSP的内置对象概述 什么是JSP的内置对象
  5. Python实现2ASK,2FSK和2PSK调制与解调
  6. 2019-8-6-在-Gitlab-开启-MatterMost-机器人
  7. 计算机语言中脚本的意思,文字脚本是什么意思
  8. 试题 算法提高 密室逃脱 java 题解 1183
  9. Plc与单片机的区别,哪个待遇更好?
  10. 服务器性能监控之性能计数器