java内存模型起源

java-MMmodel

一.java内存模型起源

1.单线程 —> 程序执行过程发展

2.分析单线程、多线程在单核cpu、多核cpu中的影响

  单线程 : CPU 核心缓存只被一个线程访问。缓存独占,不会出现访问冲突等问题。

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

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

3.硬件导致的数据问题

  处理器优化:为了使处理器内部的运算单元能够被充分利用,处理器可能会对输入代码进行乱序执行处理。

  指令重排:很多编程语言的编译器也有类似的优化,如 Java 虚拟机的即时编译器(JIT)也会做指令重排。

4.并发编程,为了保证数据的安全,需要满足三个特性

  原子性(处理器优化:在一个操作中,CPU 不可以中途暂停然后再调度,即不被中断操作,要么执行完成,要么就不执行。

  可见性(缓存一致性:当多个线程访问同一个变量时,一个线程修改这个变量的值,其他线程能够立即看得到修改的值。

  有序性(指令重排:即程序执行的顺序按照代码的先后顺序执行。

5.什么是java内存模型

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

6.java内存模型如何解决数据问题

  (1)原子性:使用 Synchronized 来保证方法和代码块内的操作是原子性的,底层实现(两个高级的字节码指令 Monitorenter 和 Monitorexit)

  (2)可见性:被Volatile 关键字修饰的变量,在被修改后立即同步到主内存,每次使用前从主内存刷新。Synchronized 和 Final 两个关键字也可以实现可见性,只是实现方式不同。

  (3)有序性:Volatile 关键字会禁止指令重排,Synchronized 关键字保证同一时刻只允许一条线程操作。

7.内存模型解决并发问题主要采用两种方式:(重点)

  (1).限制处理器优化

  (2).使用内存屏障:Java 内存模型规定所有的变量都存储在主内存中,每条线程都有自己独享的工作内存

  A:线程的工作内存中保存了该线程中用到的变量的主内存副本拷贝,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存。

  B:不同的线程之间无法直接访问对方工作内存中的变量,线程间变量的传递均需要自己的工作内存和主存之间进行数据同步进行。

  C:java内存模型(Java Memory Model)作用于工作内存和主存之间数据同步过程,它规定了如何做数据同步以及什么时候做数据同步。

参考:https://chenweistudy.github.io/2020/01/15/java-mode/

文章标题:java内存模型起源

发布时间:2020-01-16, 16:53:04

最后更新:2020-01-16, 16:53:04