在介绍Java内存模型以前,先来了解一下为何要有内存模型,以及内存模型是什么。而后咱们基于对内存模型的了解,学习Java内存模型以及并发编程的三大特性。java
为何要有内存模型程序员
在计算机中,全部的运算操做都是由CPU的寄存器来完成的,CPU指令的执行须要涉及到数据的读写操做,而CPU只能访问主存中的数据。随着技术的发展,CPU的执行速度愈来愈快,而内存的访问速度没有太大的变化,致使CU每次操做主存都要等待很长的时间。因而就有了在CPU与主存之间添加缓存的设计。编程
内存模型:CPU Cache模型缓存



目前缓存的数量达到了3级,最接近CPU的缓存称为L1,而后为L2、L3和主存。因为程序指令和数据的行为和热点分布差别比较大,所以将L1又细分为L1i(istruction)、L1d(data)。多线程

CPU的出现是为了解决CPU直接访问主存效率低下的问题。程序在运行过程当中,会将运算所需的数据从主存中复制一份到Cache中,这样CPU在计算时就能够直接对CPU Cache中的数据进行读写,当运算结束后,再将Cahce中的最新数据刷新到主存中。
虽然缓存的出现极大地提高了CPU的吞吐能力,可是也致使了缓存不一致的问题。这是由于CPU都是对Cache中的数据进行读写,不一样线程之间的工做内存是相互独立的,对某个线程工做空间中的数据进行更新,可能会没法及时同步到其它缓存中。
为了保证数据的正确性,内存模型定义了共享内存系统中多线程程序读写操做行为的规范。
Java内存模型架构
Java内存模型(Java Memory Model ),简称JMM,是一种符合内存模型规范的,屏蔽了各类硬件和操做系统的访问差别的,保证了Java程序在各类平台下对内存的访问都能获得一致效果的机制及规范。其目的是解决多线程经过主内存进行通讯时,存在的原子性、可见性(缓存一致性)以及有序性问题。(关于原子性、可见性(缓存一致性)以及有序性,咱们将会在”并发编程的三大特性“中详细讲解)
JMM决定了一个线程对共享变量的写入什么时候对其它线程可见,定义了线程与主存之间的关系:
并发编程的三大特性并发
并发编程有三大特性:原子性、可见性、有序性。
-
-
原子性:是指在一次操做或屡次操做中,要么全部的操做都获得执行,要么都不执行。【相似于事务】
-
可见性:是指一个线程对共享变量进行了修改,其余线程能够当即看到修改后的值。
-
有序性:是指代码在执行过程当中的前后顺序是有序的。【Java编译器会对代码进行优化,执行顺序可能与开发者编写的顺序不一样(指令重排)】
并发编程时,保证三大特性的方式有三种:
补充高并发
Java中提供了一系列和并发处理相关的关键字,好比volatile、synchronized等,其实这些就是Java内存模型封装了底层的实现后提供给程序员使用的一些关键字。学习
参考文献优化
- 汪文君《Java高并发编程详解-多线程与架构设计》