Java内存模型

Java内存模型

概述

多任务是被证明的有效的压榨处理器能力的方式

一个服务端为多个客户端提供服务是常见的场景,并发协调是否有效大大影响了程序的效率

Java语言和JVM提供了很多工具大大降低了并发编程的门槛。但程序员不能过度依赖这些语言和框架,才能真正利用好这些工具

服务器常用的衡量性能量化指标:TPS, Transactions Per Second; 数据库常用的衡量性能量化指标:QPS, Queries Per Second

硬件效率与一致性

学习Java的并发,可以通过物理计算机中的并发问题找到相似点,有很大的参考意义。

  1. 让计算机并发->充分利用计算机的性能,值得商榷 大多数运算任务,不止是依靠处理器,还需要与内存交互

存储与CPU性能的差距,需要在中间加一层高速缓存(Cache),作为内存与处理器之间的缓冲。

Cache引入问题:Cache Coherence,缓存一致性。每个处理器都有自己的高速缓存,却同享同一个主存。

此处应该有图:处理器,高速缓存,主内存的关系

  1. 除了高速缓存的问题,还有指令乱序执行 目的是为了内部计算单元能够尽量被充分利用

Java内存模型

JMM, Java Memory Model, 用于屏蔽各种硬件和操作系统的内存访问差异,达到多平台的一致性;C/C++直接使用物理硬件和操作系统的内存模型

在JMM的设计上,必须足够严谨用于保证正确性,也需要保证足够宽松,能够更好地使用硬件的各种特性。

主内存和工作内存

JMM的目标定义各个变量的访问规则:存取变量的细节

局部变量,方法参数都是线程私有,不会被共享,不会出现竞争问题

主内存类比物理机主内存;工作内存类比处理器告诉缓存。Working Memory 保存了变量的主内存副本,实际上是拷贝的引用和对象在某个线程中访问到的字段

不同线程的工作内存是独立的,这就是容易出现问题的地方

不准确的对应。

  1. 与JVM对应:主内存->Java堆中的实例数据部分;工作内存->虚拟机栈中的部分区域
  2. 与物理机对应:主内存->硬件内存;JVM则会将Working Memory 放在寄存器和高速缓存中

内存间的交互

交互的操作都可以视为是原子性的。除了double和long在某些平台有例外

交互操作:
  1. lock, unlock : 作用于主内存变量,标示线程的独占状态
  2. 作用于主内存:read, write
  3. 作用于工作内存:load, store。与执行引擎相关:use, assign
交互原则

略微繁琐,可以使用“先行发生”原则来等效保证

对于 volatile 型变量的特殊规则

最轻量级的同步机制

voatile 的变量具备两种特性:

  1. 保证对于其他线程的可见性:新值对于其他线程是立即可知的
  2. 禁止指令重排

值得注意的问题,由于 Java 里面的运算并非原子操作,导致操作栈栈顶的值是过期数据。

如果要安全使用voatile,必须保证下面条件:(核心就是没有依赖)

  1. 运算结果不依赖变量的当前值(比如直接赋值),单一线程访问(这就是废话)
  2. 变量不需要与其他的状态变量共同参与不变约束。

可以用于单例模式的创建。如果不适用voatile,则可以用以下代码:

public static Singleton getInstance() {
    if (instance == null) {
        synchronized(Singleton.class) {
            Singleton tmp = instance;
            if (tmp == null) {
                synchronized(Singlet.class) {
                    tmp = new Singleton();
                }
                instance = tmp;
            }
        }
    }
    return instance;
}

优化版本:
public static Singleton getInstance() {
    if (instance == null) {
        synchronized(Singleton.class) {
            Singleton tmp = instance;
            if (tmp == null) {
                synchronized(Singleton.class) {
                    instance = new Singleton();
                }
            }
        }
    }
    return instance;
}

你可能感兴趣的:(Java内存模型)