执行methodOne()的每个线程也将创建自己的localVariable2副本 。但是 , localVariable2的两个不同副本最终都指向堆上的同一个对象 。代码将localVariable2设置为指向静态变量引用的对象 。静态变量只有一个副本,此副本存储在堆上 。因此,localVariable2的两个副本最终都指向静态变量指向的MySharedObject的同一个实例 。MySharedObject实例也存储在堆上 。它对应于上图中的对象3 。
注意MySharedObject类还包含两个成员变量 。成员变量本身与对象一起存储在堆上 。两个成员变量指向另外两个Integer对象 。这些Integer对象对应于上图中的Object 2和Object 4 。
另请注意methodTwo()如何创建名为localVariable1的局部变量 。此局部变量是对Integer对象的对象引用 。该方法将localVariable1引用设置为指向新的Integer实例 。localVariable1引用将存储在执行methodTwo()的每个线程的一个副本中 。实例化的两个Integer对象将存储在堆上,但由于该方法每次执行该方法时都会创建一个新的Integer对象,因此执行此方法的两个线程将创建单独的Integer实例 。在methodTwo()中创建的Integer对象对应于上图中的Object 1和Object 5 。
另请注意类型为long的MySharedObject类中的两个成员变量,它们是基本类型 。由于这些变量是成员变量 , 因此它们仍与对象一起存储在堆上 。只有局部变量存储在线程堆栈中 。
JMM与硬件内存结构关系硬件内存结构简介现代硬件内存架构与内部Java内存模型略有不同 。了解硬件内存架构也很重要,以了解Java内存模型如何与其一起工作 。本节介绍了常见的硬件内存架构,后面的部分将介绍Java内存模型如何与其配合使用 。
这是现代计算机硬件架构的简化图:

文章插图
图片
现代计算机通常有2个或更多CPU 。其中一些CPU也可能有多个内核 。关键是,在具有2个或更多CPU的现代计算机上,可以同时运行多个线程 。每个CPU都能够在任何给定时间运行一个线程 。这意味着如果您的Java应用程序是多线程的,线程真的在可能同时运行.
每个CPU基本上都包含一组在CPU内存中的寄存器 。CPU可以在这些寄存器上执行的操作比在主存储器中对变量执行的操作快得多 。这是因为CPU可以比访问主存储器更快地访问这些寄存器 。
每个CPU还可以具有CPU高速缓存存储器层 。事实上 , 大多数现代CPU都有一些大小的缓存存储层 。CPU可以比主存储器更快地访问其高速缓存存储器,但通常不会像访问其内部寄存器那样快 。因此,CPU高速缓存存储器介于内部寄存器和主存储器的速度之间 。某些CPU可能有多个缓存层(级别1和级别2),但要了解Java内存模型如何与内存交互,这一点并不重要 。重要的是要知道CPU可以有某种缓存存储层 。
计算机还包含主存储区(RAM) 。所有CPU都可以访问主内存 。主存储区通常比CPU的高速缓存存储器大得多 。同时访问速度也就较慢.
通常,当CPU需要访问主存储器时,它会将部分主存储器读入其CPU缓存 。它甚至可以将部分缓存读入其内部寄存器,然后对其执行操作 。当CPU需要将结果写回主存储器时,它会将值从其内部寄存器刷新到高速缓冲存储器,并在某些时候将值刷新回主存储器 。
JMM与硬件内存连接 - 引入如前所述,Java内存模型和硬件内存架构是不同的 。硬件内存架构不区分线程堆栈和堆 。在硬件上,线程堆栈和堆都位于主存储器中 。线程堆栈和堆的一部分有时可能存在于CPU高速缓存和内部CPU寄存器中 。这在图中说明:

文章插图
图片
当对象和变量可以存储在计算机的各种不同存储区域中时,可能会出现某些问题 。两个主要问题是:
- Visibility of thread updates (writes) to shared variables.
- Race conditions when reading, checking and writing shared variables. 以下各节将解释这两个问题 。
想象一下,共享对象最初存储在主存储器中 。然后,在CPU上运行的线程将共享对象读入其CPU缓存中 。它在那里对共享对象进行了更改 。只要CPU缓存尚未刷新回主内存,共享对象的更改版本对于在其他CPU上运行的线程是不可见的 。这样,每个线程最终都可能拥有自己的共享对象副本,每个副本都位于不同的CPU缓存中 。
推荐阅读
- 一文读懂Kubernetes部署策略
- 如何降低小米手机发热的概率?一文带你了解
- 一文了解托管在亚马逊云科技的向量数据库MyScale
- 一文教你学会使用Nginx
- 一文了解Redis的持久化
- 一文聊聊如何快速监控 Oracle 数据库
- 一文带你掌握Containerd
- 一文了解TikTok店铺类型,美国本土店VS跨境店有什么区别?如何入驻?
- 想要搞定一个女人,只需在这四个方面用力就行,能轻松让她“动情
- 搞定流畅性过后,安卓旗舰手机游戏体验还要什么?
