广告
返回顶部
首页 > 资讯 > 精选 >Java内存模型的知识点有哪些
  • 114
分享到

Java内存模型的知识点有哪些

2023-06-16 18:06:38 114人浏览 独家记忆
摘要

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

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

关于 Java  内存模型,我们还是先从硬件内存模型入手。

硬件内存模型

先来看看硬件内存简单架构,如下图所示:

Java内存模型的知识点有哪些

硬件内存结构

这是一幅简单的硬件内存结构图,真实的结构图要比这复杂很多,特别是在缓存层,现在的计算机中 CPU 缓存一般有三层,你也可以打开你的电脑看看,打开  任务资源管理器 ---> 性能 ---> cpu ,如下图所示:

Java内存模型的知识点有哪些 

CPU 缓存

从图中可以看出我这台机器的 CPU 有三级缓存,一级缓存 (L1) 、二级缓存(L2)、三级缓存(L3),一级缓存是最接近 CPU  的,三级缓存是最接近内存的,每一级缓存的数据都是下一级缓存的一部分。三级缓存架构如下图所示:

Java内存模型的知识点有哪些 

现在我们对硬件内存架构有了一定的了解,我们来弄明白一个问题,为什么需要在 CPU 和内存之间添加缓存?

关于这个问题我们就简单点说,我们知道 CPU 是高速的,而内存相对来说是低速的,这就会造成一个问题,不能充分的利用 CPU 高速的特点,因为 CPU  每次从内存里获取数据的话都需要等待,这样就浪费了 CPU 高速的性能,缓存的出现就是用来消除 CPU 与内存之间差距的。缓存的速度要大于内存小于 CPU  ,加入缓存之后,CPU 直接从缓存中读取数据,因为缓存还是比较快的,所以这样就充分利用了 CPU  高速的特性。但也不是每次都能从缓存中读取到数据,这个跟我们项目中使用的 redis 等缓存工具一样,也存在一个缓存命中率,在 CPU 中,先查找 L1  Cache,如果 L1 Cache 没有命中,就往 L2 Cache 里继续找,依此类推,最后没找到的话直接从内存中取,然后添加到缓存中。当然当 CPU  需要写数据到主存时,同样会先刷新寄存器中的数据到 CPU 缓存,然后再把数据刷新到主内存中。

也许你已经看出了这个框架的弊端,在单核时代只有一个处理器核心,读/写操作完全都是由单核完成,没什么问题;但是多核架构,一个核修改主存后,其他核心并不知道数据已经失效,继续傻傻的使用主存或者自己缓存层的数据,那么就会导致数据不一致的情况。关于这个问题  CPU 硬件厂商也提供了解决办法,叫做缓存一致性协议(MESI 协议),缓存一致性协议这东西我也不了解,我也说不清,所以就不在这里 BB  了,有兴趣的可以自行研究。

聊完了硬件内存架构,我们将焦点回到我们的主题 Java 内存模型上,下面就一起来聊一聊 Java 内存模型。

Java 内存模型

Java 内存模型是什么?Java 内存模型可以理解为遵照多核硬件架构的设计,用 Java 实现了一套 JVM  层面的“缓存一致性”,这样就可以规避 CPU 硬件厂商的标准不一样带来的风险。好了,正式介绍一下 Java 内存模型:Java 内存模型 ( Java  Memory Model,简称 JMM ),本身是种抽象的概念,并不是像硬件架构一样真实存在的,它描述的是一组规则或规范,通过这组规范定义了程序中各个变量  (包括实例字段、静态字段和构成数组对象的元素) 的访问方式,更多关于 Java 内存模型知识可以阅读 jsR 133 :Java 内存模型与线程规范。

我们知道 JVM 运行程序的实体是线程,在上一篇 JVM 内存结构中我们得知每个线程创建时,JVM 都会为其创建一个工作内存 ( Java 栈  ),用于存储线程私有数据,而 Java 内存模型中规定所有变量都存储在主内存,主内存是共享内存区域,所有线程都可以访问,但线程对变量的操作 ( 读取赋值等 )  必须在工作内存中进行,首先要将变量从主内存拷贝到自己的工作内存空间,然后对变量进行操作,操作完后再将变量写回主内存,不能直接操作主内存中的变量。

我们知道 Java 栈是每个线程私有的数据区域,别的线程无法访问到不同线程的私有数据,所以线程需要通信的话,就必须通过主内存来完成,Java  内存模型就是夹在这两者之间的一组规范,我们先来看看这个抽象架构图:

Java内存模型的知识点有哪些

图片来源网络

从结构图来看,如果线程 A 与线程 B 之间需要通信的话,必须要经历下面 2 个步骤:

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区

  2. 首先,线程 A 把本地内存 A 中的共享变量副本中的值刷新到主内存中去。

  3. 然后,线程 B 到主内存中去读取线程 A 更新之后的值,这样线程 A 中的变量值就到了线程 B 中。

我们来看一个具体的例子来加深一下理解,看下面这张图:

Java内存模型的知识点有哪些

现在线程 A 需要和线程 B 通信,我们已经知道线程之间通信的两部曲了,假设初始时,这三个内存中的 x 值都为 0。线程 A 在执行时,把更新后的 x  值(假设值为 1)临时存放在自己的本地内存 A 中。当线程 A 和线程 B 需要通信时,线程 A 首先会把自己本地内存中修改后的 x  值刷新到主内存中,此时主内存中的 x 值变为了 1。随后,线程 B 到主内存中去读取线程 A 更新后的 x 值,此时线程 B 的本地内存的 x 值也变为了  1,这样就完成了一次通信。

JMM 通过控制主内存与每个线程的本地内存之间的交互,来为 Java 程序员提供内存可见性保证。Java  内存模型除了定义了一套规范,还提供了一系列原语,封装了底层实现后,供开发者直接使用。这套实现也就是我们常用的volatile、synchronized、final  等。

Happens-Before内存模型

Happens-Before 内存模型或许叫做 Happens-Before 原则更为合适,在 《JSR 133  :Java 内存模型与线程规范》中,Happens-Before 内存模型被定义成 Java 内存模型近似模型,Happens-Before  原则要说明的是关于可见性的一组偏序关系。

为了方便程序员开发,将底层的繁琐细节屏蔽掉,Java 内存模型 定义了 Happens-Before 原则。只要我们理解了 Happens-Before  原则,无需了解 JVM 底层的内存操作,就可以解决在并发编程中遇到的变量可见性问题。JVM 定义的 Happens-Before  原则是一组偏序关系:对于两个操作 A 和 B,这两个操作可以在不同的线程中执行。如果 A Happens-Before B,那么可以保证,当 A  操作执行完后,A 操作的执行结果对 B 操作是可见的。

Happens-Before 原则一共包括 8 条,下面我们一起简单的学习一下这 8 条规则。

1、程序顺序规则

这条规则是指在一个线程中,按照程序顺序,前面的操作 Happens-Before  于后续的任意操作。这一条规则还是非常好理解的,看下面这一段代码

class Test{ 1   int x ; 2   int y ; 3   public void run(){ 4       y = 20; 5       x = 12;     } }

第四行代码要 Happens-Before 于第五行代码,也就是按照代码的顺序来。

2、锁定规则

这条规则是指对一个的解锁 Happens-Before  于后续对这个锁的加锁。例如下面的代码,在进入同步块之前,会自动加锁,而在代码块执行完会自动释放锁,加锁以及释放锁都是编译器帮我们实现的

synchronized (this) {     // 此处自动加锁     // x 是共享变量, 初始值 =10     if (this.x < 12) {        this.x = 12;     } } // 此处自动解锁

对于锁定规则可以这样理解:假设 x 的初始值是 10,线程 A 执行完代码块后 x 的值会变成 12(执行完自动释放锁),线程 B  进入代码块时,能够看到线程 A 对 x 的写操作,也就是线程 B 能够看到 x==12。

3、volatile 变量规则

这条规则是指对一个 volatile 变量的写操作及这个写操作之前的所有操作 Happens-Before  对这个变量的读操作及这个读操作之后的所有操作。

4、线程启动规则

这条规则是指主线程 A 启动子线程 B 后,子线程 B 能够看到主线程在启动子线程 B 前的操作。

public class Demo {     private static int count = 0;     public static void main(String[] args) throws InterruptedException {         Thread t1 = new Thread(() -> {             System.out.println(count);         });         count = 12;         t1.start();     } }

子线程 t1 能够看见主线程对 count 变量的修改,所以在线程中打印出来的是 12 。这也就是线程启动规则

5、线程结束规则

这条是关于线程等待的。它是指主线程 A 等待子线程 B 完成(主线程 A 通过调用子线程 B 的 join() 方法实现),当子线程 B  完成后(主线程 A 中 join() 方法返回),主线程能够看到子线程的操作。当然所谓的“看到”,指的是对共享变量的操作。

public class Demo {     private static int count = 0;     public static void main(String[] args) throws InterruptedException {         Thread t1 = new Thread(() -> {             // t1 线程修改了变量             count = 12;         });         t1.start();         t1.join();         // mian 线程可以看到 t1 线程改修后的变量         System.out.println(count);     } }

6、中断规则

一个线程在另一个线程上调用 interrupt ,Happens-Before 被中断线程检测到 interrupt 被调用。

public class Demo {     private static int count = 0;     public static void main(String[] args) throws InterruptedException {         Thread t1 = new Thread(() -> {             // t1 线程可以看到被中断前的数据             System.out.println(count);         });         t1.start();         count = 25;         // t1 线程被中断         t1.interrupt();     } }

mian 线程中调用了 t1 线程的 interrupt() 方法,mian 对 count 的修改对 t1 线程是可见的。

7、终结器规则

一个对象的构造函数执行结束 Happens-Before 它的  finalize()方法的开始。“结束”和“开始”表明在时间上,一个对象的构造函数必须在它的  finalize()方法调用时执行完。根据这条原则,可以确保在对象的 finalize 方法执行时,该对象的所有 field 字段值都是可见的。

8、传递性规则

这条规则是指如果 A Happens-Before B,且 B Happens-Before C,那么 A Happens- Before  C。

到此,关于“Java内存模型的知识点有哪些”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: Java内存模型的知识点有哪些

本文链接: https://www.lsjlt.com/news/284641.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

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

下载Word文档
猜你喜欢
  • Java内存模型的知识点有哪些
    这篇文章主要介绍“Java内存模型的知识点有哪些”,在日常操作中,相信很多人在Java内存模型的知识点有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java内存模型的知识点有哪些”的疑惑有所帮助!接下来...
    99+
    2023-06-16
  • Redis内存模型及应用知识点有哪些
    这篇文章主要介绍了Redis内存模型及应用知识点有哪些的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Redis内存模型及应用知识点有哪些文章都会有所收获,下面我们一起来看看吧。...
    99+
    2022-10-19
  • C++内存模型与名称空间的知识点有哪些
    这篇文章主要介绍“C++内存模型与名称空间的知识点有哪些”,在日常操作中,相信很多人在C++内存模型与名称空间的知识点有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++内存模型与名称空间的知识点有哪些...
    99+
    2023-07-04
  • Java泛型知识点有哪些
    本篇内容介绍了“Java泛型知识点有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! 一 什么是泛型Java 泛型(generi...
    99+
    2023-06-15
  • JVM虚拟机内存模型与高效并发知识点有哪些
    这篇文章主要讲解了“JVM虚拟机内存模型与高效并发知识点有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JVM虚拟机内存模型与高效并发知识点有哪些”吧!Java内存模型,即Java Me...
    99+
    2023-06-02
  • 有哪些数据库内存知识点
    本篇内容介绍了“有哪些数据库内存知识点”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、如何看懂内存指标遇...
    99+
    2022-10-18
  • Linux系统内存知识点有哪些
    这篇文章主要介绍Linux系统内存知识点有哪些,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、走进 linux 内存1、内存是什么?1)内存又称主存,是 CPU 能直接寻址的存储空间,由半导体器件制成2)内存的特点...
    99+
    2023-06-15
  • Linux内存管理的知识点有哪些
    这篇文章主要介绍“Linux内存管理的知识点有哪些”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Linux内存管理的知识点有哪些”文章能帮助大家解决问题。1 前言内存管理是Linux内核中非常重要的...
    99+
    2023-06-16
  • C++内存管理的知识点有哪些
    这篇文章主要讲解了“C++内存管理的知识点有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++内存管理的知识点有哪些”吧!1. 简述下C++的内存分配方式。在C++中,内存可以分为 5...
    99+
    2023-07-05
  • .NET内存分配的知识点有哪些
    这篇文章主要讲解了“.NET内存分配的知识点有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“.NET内存分配的知识点有哪些”吧!在分析内存分配时,应该先了解关于堆栈的区别堆的分配向高地址...
    99+
    2023-06-17
  • CSS盒模型的相关知识点有哪些
    本篇内容主要讲解“CSS盒模型的相关知识点有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“CSS盒模型的相关知识点有哪些”吧!我们先看个例子:下面的 div 元素的总宽度是多少呢?<!...
    99+
    2023-07-06
  • Oracle内存和架构知识点有哪些
    本篇内容介绍了“Oracle内存和架构知识点有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Oracl...
    99+
    2022-10-19
  • Linux内核中的内存屏障知识点有哪些
    本篇内容主要讲解“Linux内核中的内存屏障知识点有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Linux内核中的内存屏障知识点有哪些”吧!缓存一致性之前一直认为linux中很多东西是用来...
    99+
    2023-06-16
  • Java常见知识点中Jvm内存结构、Java内存模型、Java对象模型的区别是什么
    这篇文章将为大家详细讲解有关Java常见知识点中Jvm内存结构、Java内存模型、Java对象模型的区别是什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。我们都知道,Java代码是要运行在...
    99+
    2023-06-05
  • DOM文档对象模型的知识点有哪些
    这篇文章主要介绍了DOM文档对象模型的知识点有哪些的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇DOM文档对象模型的知识点有哪些文章都会有所收获,下面我们一起来看看吧。D:do...
    99+
    2022-10-19
  • java jvm内存模型有哪些
    Java虚拟机(JVM)内存模型主要有以下几个部分:1. 堆内存(Heap):用于存储Java对象的实例以及数组。堆内存是所有线程共...
    99+
    2023-10-12
    java jvm
  • Java的Queue知识点有哪些
    本篇内容主要讲解“Java的Queue知识点有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java的Queue知识点有哪些”吧!Java提供了Quere,相当好用,在1.5版本中又有增强。...
    99+
    2023-06-03
  • Java NIO的知识点有哪些
    今天小编给大家分享一下Java NIO的知识点有哪些的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。No-Block 和Blo...
    99+
    2023-06-17
  • Java栈的知识点有哪些
    这篇文章主要介绍了Java栈的知识点有哪些的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java栈的知识点有哪些文章都会有所收获,下面我们一起来看看吧。1.栈的概念栈(stack)又名堆栈,作为一种数据结构,是...
    99+
    2023-06-29
  • java的Classpath知识点有哪些
    本篇内容主要讲解“java的Classpath知识点有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“java的Classpath知识点有哪些”吧!java的优点就是他是一个自动支持网络功能的...
    99+
    2023-06-03
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作