补充-Java内存模型

想一想为什么要有内存模型呢?
众所周知,计算机在执行程序的时候,每一条指令都是在CPU中执行的,在指令执行的时候又需要用到数据,但计算机上的数据是存在计算机的物理内存(主存)上的,所以每次指令在CPU中执行的时候都需要先在主存上把数据取出来,刚开始的时候还可以,但是随着CPU的高速发展,CPU的执行速度越来越快,但内存的技术并没有太大提升,所以从内存中读取和写入数据的过程需要很漫长的时间,但是CPU的执行速度很快,这就造成CPU每次存在内存都需要花费很多无用的等待时间。

但又不能因此不发展CPU了,所以人们就想了一个办法,就是在CPU和内存之间加了高速缓存,就相当于保存一份数据拷贝。高速缓存的特点就是速度快,内存小,但很昂贵。

引入高速缓存之后,程序的执行过程就变成了这样:
在程序的运行过程中会将运算需要的数据从主存赋值一份到CPU的高速缓存中,这时CPU执行指令时,需要用到数据就可以直接从它的高速缓存读取和写入数据,在运算结束后,再将高速缓存中写入的数据刷新到主存当中。

而CPU的能力是不断提升的,一层缓存就慢慢的无法满足要求了,就出现了多级缓存。

按照数据读取顺序和与CPU结合的紧密程度,CPU缓存可以分为一级缓存(L1)、二级缓存(L2)、三级缓存(L3),每一级缓存中所存储的全部数据都是下一级缓存的一部分。

这样,当CPU要读取一个数据时,首先从一级缓存中查找,如果没有找到再从二级缓存中查找,如果还是没有就从三级缓存或内存中查找。

单核CPU只含有一套L1、L2、L3缓存。
如果是多核CPU,则每个核心都含有一套L1(甚至和L2)缓存,而共享L3(或者和L2)缓存。

计算机是支持多线程的。
单线程:CPU核心的缓存只被一个线程访问,缓存独占,不会出现访问冲突等问题。
单核CPU,多线程:进程中的多个线程会同时访问进程中的共享数据,CPU将某块内存加载到缓存后,不同线程在访问相同的物理地址的时候,都会映射到相同的缓存位置,这样即使发生线程的切换,缓存仍然不会失效。由于任何时刻只能有一个线程在执行,因此不会出现缓存访问冲突。
多核CPU,多线程:每个核都至少有一个L1缓存。多个线程访问进程中的某个共享内存,且这多个线程分别在不同的核心上执行,则每个核心都会在各自的caehe中保留一份共享内存的缓冲。由于多核是可以并行的,可能会出现多个线程同时写各自的缓存的情况,而各自的caehe之间的数据就有可能不同。

在CPU和主存之间增加缓存,在多线程场景下就可能存在缓存一致性问题,也就是说,在多核CPU中,每个核的自己缓存中,关于同一个数据的缓存内容可能不一致。

这样说可能有点抽象,就举个例子说明吧。
假设一家公司CEO下边有2个经理(经理管理的底层人员是共用的),CEO下达的命令是要进行人员调动,经理A想裁掉张三,可是经理B想给张三升职,A已经把张三裁掉了,可是B并不知道,他认为站三还在职,所以会执行给张三升职这条命令。

处理器优化和指令重排也会造成缓存一致性问题

一直在说缓存一致性问题,那它到底是什么问题呢?
原子性是指一个操作中CPU不可以在中途暂停然后再调度,要不执行完成,要不就不执行。
可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值被其他线程能够立即看到修改后的值。
有序性是指程序执行的顺序按照代码的先后顺序执行。

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

那如何解决缓存一致性问题呢?
这时候内存模型就出现了。
为了保证共享内存的正确性(可见性、有序性、原子性),内存模型定义了共享内存系统中多线程程序读写操作行为的规范(happens-before原则)。
可以在我的这篇博客中看看这个原则的具体要求:https://blog.csdn.net/huaijiu123/article/details/87345899

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

Java内存模型规定了所有的变量都存储在主内存中,每个线程还有自己的工作内存,线程的工作内存中保存了该线程中用到的变量(从主内存拷贝过来的副本),线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存。不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量的传递均需要自己的工作内存和主内存之间进行数据同步。

Java内存模型的实现
Java内存模型就是依靠volatile、synchronized、final这些关键字实现的,具体请看这篇博客:https://blog.csdn.net/huaijiu123/article/details/87345899

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值