我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java内存模型该怎么理解

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

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java内存模型该怎么理解

这篇文章主要讲解了“Java内存模型该怎么理解”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java内存模型该怎么理解”吧!

1.为什么会误解

首先,我们先来分析一下问什么很多人,甚至是大多数人会答非所问呢?

我觉得主要有几个原因:

Java内存模型,这个词听着太像是关于内存分布的知识了。听上去和并发编程没有半毛钱关系。

网上很多资料都是错的。不信你去网上搜索一下"Java内存模型",你会发现,很多人打着内存模型的,介绍了JVM内存结构的知识。

还存在一种情况,虽然不多见,但是也有。那就是很多面试官自己也以为内存模型就是要介绍堆、栈、方法区这些知识。就导致有时候面试者不知道自己到底应该如何回答。

那么,到底什么是Java内存模型?关于这道面试题应该如何回答呢?

2.什么是内存模型

我曾经在《再有人问你Java内存模型是什么,就把这篇文章发给他》中详细的介绍过Java内存模型的来龙去脉,这里再重新回顾一下。

Java内存模型是根据英文Java Memory  Model(JMM)翻译过来的。其实JMM并不像JVM内存结构一样是真实存在的。他只是一个抽象的概念。

Java内存模型的相关知识在 JSR-133: Java Memory Model and Thread Specification  中描述的。JMM是和多线程相关的,他描述了一组规则或规范,这个规范定义了一个线程对共享变量的写入时对另一个线程是可见的。

Java内存模型(Java Memory Model  ,JMM)就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了Java程序在各种平台下对内存的访问都能得到一致效果的机制及规范。目的是解决由于多线程通过共享内存进行通信时,存在的原子性、可见性(缓存一致性)以及有序性问题。

那么,我们这里就先来说说什么是所谓的内存模型规范、这里提到的原子性、可见性以及有序性又是什么东西?

原子性

线程是CPU调度的基本单位。CPU有时间片的概念,会根据不同的调度算法进行线程调度。所以在多线程场景下,就会发生原子性问题。因为线程在执行一个读改写操作时,在执行完读改之后,时间片耗完,就会被要求放弃CPU,并等待重新调度。这种情况下,读改写就不是一个原子操作。即存在原子性问题。

缓存一致性

在多核CPU,多线程的场景中,每个核都至少有一个L1  缓存。多个线程访问进程中的某个共享内存,且这多个线程分别在不同的核心上执行,则每个核心都会在各自的caehe中保留一份共享内存的缓冲。由于多核是可以并行的,可能会出现多个线程同时写各自的缓存的情况,而各自的cache之间的数据就有可能不同。

在CPU和主存之间增加缓存,在多线程场景下就可能存在缓存一致性问题,也就是说,在多核CPU中,每个核的自己的缓存中,关于同一个数据的缓存内容可能不一致。

有序性

除了引入了时间片以外,由于处理器优化和指令重排等,CPU还可能对输入代码进行乱序执行,比如load->add->save  有可能被优化成load->save->add 。这就是有序性问题。

多CPU多级缓存导致的一致性问题、CPU时间片机制导致的原子性问题、以及处理器优化和指令重排导致的有序性问题等,都硬件的不断升级导致的。那么,有没有什么机制可以很好的解决上面的这些问题呢?

最简单直接的做法就是废除处理器和处理器的优化技术、废除CPU缓存,让CPU直接和主存交互。但是,这么做虽然可以保证多线程下的并发问题。但是,这就有点因噎废食了。

所以,为了保证并发编程中可以满足原子性、可见性及有序性。有一个重要的概念,那就是——内存模型。

为了保证共享内存的正确性(可见性、有序性、原子性),内存模型定义了共享内存系统中多线程程序读写操作行为的规范。通过这些规则来规范对内存的读写操作,从而保证指令执行的正确性。它与处理器有关、与缓存有关、与并发有关、与编译器也有关。他解决了CPU多级缓存、处理器优化、指令重排等导致的内存访问问题,保证了并发场景下的一致性、原子性和有序性。

针对上面的这些问题,不同的操作系统都有不同的解决方案,而Java语言为了屏蔽掉底层的差异,定义了一套属于Java语言的内存模型规范,即Java内存模型。

Java内存模型规定了所有的变量都存储在主内存中,每条线程还有自己的工作内存,线程的工作内存中保存了该线程中是用到的变量的主内存副本拷贝,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存。不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量的传递均需要自己的工作内存和主存之间进行数据同步进行。

而JMM就作用于工作内存和主存之间数据同步过程。他规定了如何做数据同步以及什么时候做数据同步。

3.Java内存模型的实现

了解Java多线程的朋友都知道,在Java中提供了一系列和并发处理相关的关键字,比如volatile、synchronized、final、concurren包等。其实这些就是Java内存模型封装了底层的实现后提供给程序员使用的一些关键字。

在开发多线程的代码的时候,我们可以直接使用synchronized等关键字来控制并发,从来就不需要关心底层的编译器优化、缓存一致性等问题。所以,Java内存模型,除了定义了一套规范,还提供了一系列原语,封装了底层实现后,供开发者直接使用。

本文并不准备把所有的关键字逐一介绍其用法,因为关于各个关键字的用法,网上有很多资料。读者可以自行学习。本文还有一个重点要介绍的就是,我们前面提到,并发编程要解决原子性、有序性和一致性的问题,我们就再来看下,在Java中,分别使用什么方式来保证。

原子性

在Java中,为了保证原子性,提供了两个高级的字节码指令monitorenter和monitorexit。在synchronized的实现原理文章中,介绍过,这两个字节码,在Java中对应的关键字就是synchronized。

因此,在Java中可以使用synchronized来保证方法和代码块内的操作是原子性的。

可见性

Java内存模型是通过在变量修改后将新值同步回主内存,在变量读取前从主内存刷新变量值的这种依赖主内存作为传递媒介的方式来实现的。

Java中的volatile关键字提供了一个功能,那就是被其修饰的变量在被修改后可以立即同步到主内存,被其修饰的变量在每次是用之前都从主内存刷新。因此,可以使用volatile来保证多线程操作时变量的可见性。

除了volatile,Java中的synchronized和final两个关键字也可以实现可见性。只不过实现方式不同,这里不再展开了。

有序性

在Java中,可以使用synchronized和volatile来保证多线程之间操作的有序性。实现方式有所区别:

volatile关键字会禁止指令重排。synchronized关键字保证同一时刻只允许一条线程操作。

好了,这里简单的介绍完了Java并发编程中解决原子性、可见性以及有序性可以使用的关键字。读者可能发现了,好像synchronized关键字是***的,他可以同时满足以上三种特性,这其实也是很多人滥用synchronized的原因。

但是synchronized是比较影响性能的,虽然编译器提供了很多锁优化技术,但是也不建议过度使用。

4.面试如何回答

前面我介绍完了一些和Java内存模型有关的基础知识,只是基础,并不是全部,因为随便一个知识点还是都可以展开的,如volatile是如何实现可见性的?synchronized是如何实现有序性的?

但是,当面试官问你:能简单介绍下你理解的内存模型吗?

首先,先和面试官确认一下:您说的内存模型指的是JMM,也就是和并发编程有关的那一个吧?

在得到肯定答复后,再开始介绍(如果不是,那可能就要回答堆、栈、方法区哪些了….囧… 这里也可以根据上下文自行理解面试官想要问的问题具体是什么):

Java内存模型,其实是保证了Java程序在各种平台下对内存的访问都能够得到一致效果的机制及规范。目的是解决由于多线程通过共享内存进行通信时,存在的原子性、可见性(缓存一致性)以及有序性问题。

除此之外,Java内存模型还提供了一系列原语,封装了底层实现后,供开发者直接使用。如我们常用的一些关键字:synchronized、volatile以及并发包等。

回答到这里就可以了,然后面试官可能会继续追问,然后根据他的追问再继续往下回答即可。

所以,当有人再问你Java内存模型的时候,不要一张嘴就直接回答堆栈、方法区甚至GC了,先思考下面试官的问题。

感谢各位的阅读,以上就是“Java内存模型该怎么理解”的内容了,经过本文的学习后,相信大家对Java内存模型该怎么理解这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

免责声明:

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

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

Java内存模型该怎么理解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java内存模型该怎么理解

这篇文章主要讲解了“Java内存模型该怎么理解”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java内存模型该怎么理解”吧!1.为什么会误解首先,我们先来分析一下问什么很多人,甚至是大多数人
2023-06-16

Java 内存模型,或许应该这么理解

我们从硬件、操作系统再到语言层面,知道了 Java 内存模型诞生的原因,知道其诞生就是为了解决多平台的内存模型统一问题,进一步其实就是多线程的数据一致性问题。

怎么理解Java内存模型

本篇内容主要讲解“怎么理解Java内存模型”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么理解Java内存模型”吧!内存模型的由来1. 计算机在执行程序的时候每条指令都是由CPU来执行的。而C
2023-06-16

Java内存模型技术该如何理解

Java内存模型技术该如何理解,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。  因为Java内存模型不仅是Java重点要学习的技术知识,还是面试的时候经典面试题,希望引起同
2023-06-02

怎么深入理解Java内存模型JMM

这期内容当中小编将会给大家带来有关怎么深入理解Java内存模型JMM,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Java 内存模型Java 内存模型(JMM)是一种抽象的概念,并不真实存在,它描述了一组
2023-06-05

Java虚拟机内存管理该怎么理解

今天就跟大家聊聊有关Java虚拟机内存管理该怎么理解,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Java虚拟机规范将物理内存(主内存和CPU中的缓存、寄存器)划分为程序计数器、Ja
2023-06-02

Java内存模型详解

JMM全称JavaMemoryModel,中文翻译Java内存模型,一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,本详细介绍了Java内存模型,感兴趣的同学可以参考一下
2023-05-18

Java内存模型原理是什么

这篇文章主要介绍“Java内存模型原理是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Java内存模型原理是什么”文章能帮助大家解决问题。内部原理JVM 中试图定义一种 JMM 来屏蔽各种硬件和
2023-06-02

Java内存模型JMM详解

Java Memory Model简称JMM, 是一系列的Java虚拟机平台对开发者提供的多线程环境下的内存可见性、是否可以重排序等问题的无关具体平台的统一的保证。(可能在术语上与Java运行时内存分布有歧义,后者指堆、方法区、线程栈等内存
2023-05-30

JAVA内存模型(JMM)详解

这篇文章主要介绍了JAVA内存模型(JMM)详解的相关资料,需要的朋友可以参考下
2022-12-08

Java内存区域与内存模型详解

这篇文章主要介绍“Java内存区域与内存模型详解”,在日常操作中,相信很多人在Java内存区域与内存模型详解问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java内存区域与内存模型详解”的疑惑有所帮助!接下来
2023-06-02

Java内存模型的原理是什么

这篇文章将为大家详细讲解有关Java内存模型的原理是什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。所有的编程语言中都有内存模型这个概念,区别于微架构的内存模型,高级语言的内存模型包括了编
2023-06-17

Java内存模型图文详解

1. 概述多任务和高并发是衡量一台计算机处理器的能力重要指标之一。一般衡量一个服务器性能的高低好坏,使用每秒事务处理数(Transactions Per Second,TPS)这个指标比较能说明问题,它代表着一秒内服务器平均能响应的请求数,而TPS值与程序的并
Java内存模型图文详解
2014-08-03

从 CPU 说起,深入理解 Java 内存模型!

这篇文章我们从底层 CPU 开始讲起,一直讲到操作系统,最后讲到了编程语言层面,让大家能够一环扣一环地理解,最后明白 Java 内存模型诞生的原因(上层有数据一致性问题),以及最终要解决的问题(缓存一致性问题)。

深入理解JVM内存模型

JVM内存结构包括方法区、堆、栈、本地方法栈和程序计数器。不同的内存区域有不同的作用和管理方式,合理地使用和管理内存是编写高效、稳定的Java程序的重要方面。
JVM内存2024-11-30

Java的内存模型是什么

这篇文章主要介绍“Java的内存模型是什么”,在日常操作中,相信很多人在Java的内存模型是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java的内存模型是什么”的疑惑有所帮助!接下来,请跟着小编一起来
2023-06-15

Java内存模型包含什么

Java内存模型包含以下几个部分:1. 主内存(Main Memory):主内存是所有线程共享的内存区域,用于存储对象实例、静态变量和常量等数据。2. 工作内存(Working Memory):每个线程都有自己的工作内存,用于存储线程私有的
2023-08-24

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录