白话Java基础系列—Java内存模型

本系列呢,主要将我理解的Java基础内容,以比较白话的方式,解释出来,希望能帮助大家快速的理解一些概念。

本文主要内容: 为什么要有Java内存模型?什么是Java内存模型?Java内存模型解决了什么问题?

本文内容主要参考了 Holis的博客,对我所理解的内容思路重新做了梳理, 原文链接见参考文档。

一、为什么要有Java内存模型?

缓存一致性

白话Java基础—JVM内存模型

在CPU和主存之间增加的高速缓存,在多线程环境下可能会存在缓存一致性问题。

处理器优化

为了使运算单元能够被尽量的被充分利用,处理器会对输入代码进行乱序执行处理;

指令重排

为了使运算单元能够被尽量的被充分利用,编译器会对输入代码进行乱序执行处理;

并发编程问题

原理性问题、可见性问题、有序性问题。我们说并发编程,为了保证数据安全,需要满足一下三个特性。

  • 原子性: CPU执行的最小单元,不可拆分;不可以中途暂停然后在调度。

  • 可见性: 多个线程访问一个变量时,一个线程修改了这个变量的值,其他线程能够立即得到修改的值。

  • 有序性: 程序执行的顺序按照代码的先后顺序执行。

缓存一致性问题就是可见性问题; 处理器优化导致的原子性问题和指令重排可能会导致和有序性问题;

二、什么是内存模型

为了保证共享内存的正确性(可见性、原子性、有序性),内存模型定义了共享系统中,多线程程序读写操作行未的规范。它解决了CPU多级缓存、处理器优化、指令重排等导致的内存访问问题,保证了并发场景下的一致性、原子性、有序性。

什么是Java内存模型(JMM)?

Java内存模型就是一种符合内存模型规范,屏蔽了各种硬件和操作系统访问差异的,保证了Java程序在各种平台下对内存的访问都能保证效果一致的机制及规范。

白话Java基础—JVM内存模型

三、Java内存模型解决了那些问题?

JMM是以重规范,目的是解决由于多线程通过共享内存进行通信时,存在本地内存数据不一致、编译器会对代码指令重排序、处理器会带代码处理乱序执行等带来的问题。

Java内存模型的实现

volatile,sychronized, final,concurrent包 等这些就是Java内存模型封装了底层的实现后,提供给程序员使用的一些Java 关键字。

原子性

是通过Sychronized关键字来保证的,底层是由 minitorenter和monitoexit指令。

来保证方法和代码块内的操作是原子性的。

可见性

是通过volatile关键字提供了这个功能;所修改时的变量被修改后,立马同步到主内存中,被修饰的变量每次使用(计算)之前,都从主内存中刷新。因此,可以使用volatile来保证多线程操作时变量的可见性。

除了volatile, sychronized final 也可以实现可见性,只是方式不一样。

有序性

在Java中,可以使用sychronizedvolatile保证线程之间操作的有序性。

不过方式有所差别, volatile会禁止指令重排,sychronized会保证同一时刻只有一条线程操作。

四、参考文档

再有人问你Java内存模型是什么,就把这篇文章发给他

相关文章: