美文网首页
Java内存模型

Java内存模型

作者: 阿树在简书 | 来源:发表于2018-05-13 22:25 被阅读0次

    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内存模型

          本文链接:https://www.haomeiwen.com/subject/nusrdftx.html