JMM (Java 内存模型,不是 JVM 内存结构) 和 volatile

什么是内存模型?

官方理解:在特定的操作协议下,对特性的内存或者高速缓存进行读写访问的过程抽象。

为了实现缓存一致性从而建立起来的对于变量访问的一套规则。

在计算机的 CPU 的运行速度是非常快的,但是磁盘的访问速度是非常慢的,为了使得 CPU 的性能得到充分的利用,所以出现了多任务,多个任务并发执行,带来了数据的访问可能造成不一致的情况。所以这个时候出现了缓存一致性协议,解决了这个问题。

什么是 JMM ?

在 CPU 层面,实现了数据的一致性访问,编程语言在这个方面也付出了相关的努力。在 C++ 中可以实现数据在并发情况下的并发访问安全,但是这个程序的跨平台能力很差。
举例:对于传统的内存模型,比如 C++ 的内存模型,在 linux 下面可以正常的执行程序,保证变量的线程安全,但是换到 windows 中,需要特别的针对 windows 编写代码,否则因为换了使用平台会导致并发访问出错,也就是变量不是线程安全的。

在设计 JMM 的时候,也就是设计 Java 程序中访问变量规则的时候。设计者基于虚拟机和 JMM 模型,实现了数据一致性访问以及跨平台的能力。

Java 内存模型是为了屏蔽各种硬件以及操作系统之间的内存访问差异,实现了 Java 程序在 各种平台下面都能正确的执行。这样一来相对于类似 C++ 程序进行了一定的提升。

当然 JMM 的实现是由于 JVM 的存在。

可以理解 JMM 是传统的为了保证缓存一致性协议和跨平台应用的升级版本。

JMM 的作用是什么?

JMM 的主要目的就是定义了程序中各种变量的访问规则,也可以说是一种规范。也就是关注虚拟机中把变量存储到内存中,并且从内存中取出变量值这样的底层细节。而这些底层细节就是在 JMM 中对于变量操作的相关方法,这些方法比如:lock(), unlock(), read(), load() 等… 8 个方法。通过这 8 个方法,完成了 JMM 这个规范的实现,再加上虚拟机的存在,实现了缓存一致性与跨平台。

JMM 是为了解决多线程并发过程中带来的原子性、可见性、有序性的一种规范或者规则。

怎么设计的 JMM ?

JMM 是一个规范,围绕着变量以及程序的原子性、可见性、有序性展开,使用多种技术共同的实现,下面是每个技术具体的部分。

JMM 的可见性借鉴了 MESI 这种缓存一致性协议。

1、设计了线程共享的主内存以及线程独享的工作内存

2、设计了内存之间交互操作的原子方法

lock()
unlock()
read()
load()
assign()
use()
store()
write()

3、设计了 volatile synchornized

4、设计了 long double 变量的特殊规则

64 位的这种变量,拆分成为两次的 32位操作,这个就是特殊的 long double 非原子性协议。

5、设计了先行发生 happen - before 原则

只是使用 volatile 以及 synchornized 来保证所有的有序性,那么很多操作比较繁琐,所以 Java 语言设计的时候,设计了一系列约定俗成的原则,Java 代码的执行默认按照下面的原则执行,方便了有序性的实现。

自然定义了一些原则,比如:
1、按照控制流程顺序,控制流程前面的代码早于控制流程后面的代码执行
2、对于线程所有的操作发生于线程终止之前。
3、对象的初始化早于对象的 finalize() 方法执行之前。

小结

JMM 是Java 实现并发编程的一个规范或者是一种思想,基于这种规范,这种规范主要是围绕着并发过程中如何保证原子性、可见性、有序性这三个特征建立起来的。为了实现这个规范达到目的,按照 8 种原子操作,主内存 工作内存的划分,volatile ,synchornized 先行发生的原则共同实现,使得多线程并发程序运行的原子性、可见性、有序性。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值