首页   快速返回

java内存模型     所属分类 java
计算机内存模型 Java内存模型

CPU和缓存一致性  高速缓存 主存

一级缓存(L1) 二级缓存(L2) 三级缓存(L3)
core1  L1 L2 L3  memory

单线程 多线程  单核CPU 多核CPU

单核CPU 多线程 
进程中的多个线程会同时访问进程中的共享数据,CPU将某块内存加载到缓存后,
不同线程在访问相同的物理地址的时候,都会映射到相同的缓存位置,这样即使发生线程的切换,缓存仍然不会失效。
但由于任何时刻只能有一个线程在执行,因此不会出现缓存访问冲突。

多核CPU 多线程
每个核至少有一个L1 缓存。
多个线程访问进程中的某个共享内存,且这多个线程分别在不同的核心上执行,则每个核心都会在各自的caehe中保留一份共享内存的缓冲。
由于多核是可以并行的,可能会出现多个线程同时写各自缓存的情况,而各自的cache之间的数据有可能不一致。

多核CPU中,每个核自己的缓存中,关于同一个数据的缓存内容可能不一致。

处理器优化和指令重排
处理器可能会对输入代码乱序执行
编译器也有类似优化 

并发编程问题
原子性  可见性  有序性 
缓存一致性问题 处理器优化问题 指令重排问题等

原子性是指在一个操作中就是cpu不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行。
可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。
有序性即程序执行的顺序按照代码的先后顺序执行。

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

最简单粗暴的做法就是去掉 处理器和处理器的优化技术 ,去掉CPU缓存,让CPU直接和主存交互。

内存模型用于解决这些问题

内存模型解决并发问题主要采用两种方式:限制处理器优化和使用内存屏障。

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

Java内存模型,一般指的是JDK 5 开始使用的新的内存模型,主要由JSR-133: JavaTM Memory Model and Thread Specification 描述。

http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf

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

JMM就作用于工作内存和主存之间数据同步过程,规定了如何做数据同步以及什么时候做数据同步。

主内存和工作内存,可以简单的类比成计算机内存模型中的主存和缓存的概念

需要注意的是,主内存和工作内存与JVM内存结构中的Java堆、栈、方法区等并不是同一个层次的内存划分,无法直接类比。

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

Java并发处理相关 volatile synchronized final concurrent包等

Java内存模型,除了定义了一套规范,还提供了一系列原语,封装了底层实现后,供开发者直接使用。


原子性  synchronized 字节码指令monitorenter和monitorexit

可见性 
volatile 2个作用
保证多线程操作时变量的可见性
禁止指令重排

可以使用synchronized和volatile来保证多线程之间操作的有序性
volatile 禁止指令重排
synchronized 保证同一时刻只允许一个线程操作

synchronized 可同时保证 原子性 可见性 顺序性

上一篇     下一篇
logback pattern 配置

java8的方法区

Hadoop不行了吗

spring和springboot发展历史

spring扩展点

spring bean生命周期及扩展点