3.内存间的交互操作
看到这块,小伙伴是否有这么一个疑问?不同的工作内存缓存了主内存中相同的数据,那么是否有类似于 MESI 这样的协议来保证数据一致性了?
我们先来看下内存间的交互操作吧.
内存间的交互是数据从主内存拷贝到工作内存,然后从工作内存同步会主内存的具体实现细节.
Java 内存模型定义了 8 中操作来完成,虚拟机实现时必须保证这 8 中操作都是原子操作(对于 double 和 long 型变量来说,
load、store、read 和 write 允许有例外).
(1)lock: 作用与主内存的变量,它把一个变量标识变为一个线程独占的状态.
(2)unlock: 作用于主内存的变量,解锁,只有解锁完后,其他线程才能锁定.
(3)read: 作用于主内存,把一个变量的值从主内存传入到工作内存中,以便随后的 load 动作使用(类似于实参).
(4)load: 作用于工作内存中的变量,它把 read 操作从主内存中得到的值放入工作内存的变量副本中(类似于形参).
(5)use: 作用于工作内存的变量,它把工作内存中的一个变量值传递给执行引擎,每当虚拟机遇到一个需要使用到变量的值的字节码指令时将会执行
这个操作.
(6)assign: 作用于工作内存的变量,它把一个从执行引擎接收到的值赋给工作内存的变量,每当虚拟机遇到一个给变量赋值的字节码指令时执行
这个操作.
(7)store: 作用于工作内存的变量,它把工作内存中一个变量的值传到主内存中,以便随后的 write 操作使用.
(8)write: 作用于主内存的变量,它把 store 操作从工作内存得到的变量的值放入主内存的变量中.
作用于主内存的操作:lock/unlock、read/write
作用于工作内存的操作:load/use/assign/store
对 lock/unlock 的分析:
在 JVM 中,并没有把 lock/unlock 直接开放给用户,而是提供了更高级别的 monitorenter/monitorexit 来间接操作 lock/unlock,
而 monitorenter/monitorexit 又和 synchronized 相关联. 我们知道 synchronized 在释放锁的时候,会将cache 中的值同步会主存,
这一点和 unlock 规则对应. 而 lock 只能被一个线程锁定,且对同一个线程可重入锁定.
注意:
(1)JMM 要求 read 和 load 操作以及 store 和 write 操作必须按照顺序执行(不一定连续执行).
(2)read 和 load、store 和 write 操作必须成对出现.
(3)不允许一个线程丢弃它的最近 assign 操作,即变量在工作内存中改变了之后必须把该变化同步回主内存(这里没有说立即同步喔,所以我们
会遇到多线程累加某一个变量的值100次,最后可能结果不到200).
(4)不允许一个线程无原因地(没有发生过任何 assign 操作)把数据从线程的工作内存同步回主内存中.
(5)一个新的变量只能在主内存中诞生,不允许在工作内存中直接使用一个未被初始化(load或assign)的变量,换句话说,就是对一个变量实施
use、store 操作之前,必须先执行过了 assign 和 load 操作(对应java语法规则是变量必须初始化后才能使用).
(6)一个变量在同一时刻只允许一条线程对齐进行lock操作,但lock操作可以被同一条线程重复执行多次,多次lock后,只有执行相同次数的unlock
操作,变量才会被解锁(对照 synchronized 分析).
(7)如果对一个变量执行lock操作,那将会清空工作内存中此变量的值,在执行引擎使用这个变量前,需要重新执行load或assign操作初始化
变量的值.
(8)对一个变量执行unlock操作之前,必须先把此变量同步回主内存中(执行 store、write 操作).
lock:当线程释放锁时,JMM会把该线程对应的本地内存中的共享变量刷新到主内存中
unlock:当线程获取锁时,JMM会把该线程对应的本地内存置为无效。从而使得被监视器保护的临界区代码必须从主内存中读取共享变量
分享到:
相关推荐
Java内存模型的核心内容涵盖了锁、线程间的交互、内存可见性和顺序一致性等方面。在JSR-133之前的Java内存模型规范中,volatile变量的语义较弱,它们的访问可以自由排序。但在新规范中,volatile变量的语义被加强为...
本篇文章将深入探讨Java内存模型(JMM, Java Memory Model),以及其中的内存操作规则。 Java内存模型定义了在并发环境中,如何在不同线程之间共享数据以及保证数据一致性的一组规范。它主要关注的是处理器内存和...
Java内存模型,简称JMM(Java Memory Model),是Java编程语言规范的一部分,它定义了程序中各个线程如何访问和修改共享变量,以及如何确保数据的一致性。深入理解Java内存模型对于编写高效的并发程序至关重要。本文...
综上所述,Java内存模型是一个复杂的系统,它涉及了线程间的通信与同步、共享变量的访问规则、重排序以及内存屏障等多个方面。为了编写出正确的多线程程序,深入理解Java内存模型是不可或缺的。Java内存模型的规则和...
为了确保线程间数据的一致性,Java内存模型规定了一系列复杂的规则来管理线程与共享变量之间的交互过程。 ##### 主内存与工作内存 - **主内存**:存储着各个线程共享的数据,其中每个共享变量都有一份master copy...
Java内存模型规定了程序中的变量是如何在处理器之间以及内存系统中交互的。它包括了主内存(Main Memory)和每个线程的本地内存(Thread Local Memory)。本地内存包含了线程的工作内存,其中存储了变量的副本。线程...
Java内存模型(JMM)是Java虚拟机(JVM)的一部分,它定义了程序中不同变量如何交互,特别是在多线程环境下。JMM确保了在各种硬件和操作系统平台上,Java程序的行为具有一致性和可预测性。Java内存模型的主要目标是...
Java内存模型(Java Memory Model,JMM)是Java平台中非常关键的概念,它定义了线程如何共享和访问内存中的数据,以及在多线程环境下如何保证数据的一致性。这本书"深入理解Java内存模型"显然是为了帮助读者深入探讨...
Java内存模型(Java Memory Model,简称JMM)是Java虚拟机(JVM)规范中定义的一种内存模型,它涉及了线程之间共享变量的可见性问题。在并发编程中,理解Java内存模型对于编写正确的多线程程序至关重要。 首先,...
在多线程编程中,Java内存模型涉及到线程间的内存可见性问题,即当一个线程修改了对象的共享变量后,其他线程何时能“看到”这个修改。Java内存模型通过提供synchronized关键字和volatile变量来实现线程间通信和内存...
### Java内存模型JSR-133详解 #### 引言 Java内存模型(Java Memory Model,简称JMM)是Java编程语言中的一个重要概念,它规定了程序中各种变量(线程共享变量)的访问规则,以及在并发环境中如何解决数据一致性...
MongoDB的Java驱动程序是Java开发者与MongoDB数据库进行交互的主要工具。在"mongo-java-driver-3.2.2"这个版本中,我们探讨的是一个关键的中间件,它允许Java应用程序充分利用MongoDB的功能,包括数据存储、查询、...
Java内存模型(Java Memory Model,JMM)是Java虚拟机(JVM)规范中的一个重要组成部分,它定义了程序中各个变量(包括实例域、静态域和数组元素)的访问规则,以及在实际计算机系统中如何将这些变量存储在内存和从...
同时,为了保证多线程下的数据安全,Java内存模型引入了volatile关键字、synchronized关键字以及final关键字等同步机制来保证线程间的通信。 除此之外,JMM还定义了happens-before规则,这是一组用于保证线程间操作...
1. **Java内存模型基础**:首先,书中会介绍Java内存模型的架构,包括堆内存、栈内存、方法区、程序计数器、本地方法栈等几个主要部分,解释它们各自的作用和交互方式。 2. **对象生命周期**:讨论Java对象从创建到...