zoukankan      html  css  js  c++  java
  • Java内存模型(JMM)

    Java内存模型(JMM)

    1. 计算机内存系统

    计算机在执行程序时,每条指令都是在CPU中执行的,而执行指令过程中,势必会涉及到数据的读取和写入。

    由于在程序运行过程中,临时数据是存放在主存(物理内存)中的,这时就存在一个问题,由于CPU执行指令的速度很快,而从内存读取和写入数据的过程与其相比速度要慢得多,因此如果任何时候对数据的操作都要通过和内存的交互来进行,会大大降低指令执行的速度。

    因此CPU中就有了高速缓存。当程序在运行过程中,会将运算需要的数据从主存复制一份到CPU的高速缓存中,当CPU进行计算时就可以直接从它的高速缓存中读取和写入数据,运算结束之后,再将高速缓存中的数据刷新到主存当中去。

    2. JMM内存模型

    在Java虚拟机规范中试图定义一种Java内存模型(Java Memory Model,JMM)来屏蔽各个硬件平台和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果。

    JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(Main Memory)中,每个线程都有一个私有的本地内存(Local Memory),本地内存中存储了该线程读/写共享变量的副本。

    image-20200812233547123

    如果线程A与线程B之间要通信的话,必须要经历下面2个步骤。

    • 线程A把本地内存A中更新过的共享变量刷新到主内存中去。
    • 线程B到主内存中去读取线程A之前已更新过的共享变量。

    3. JMM内存模型三大特性

    原子性:一个操作或多个操作,要么全部执行并且执行过程中不会被任何因素打断,要么就不执行。

    • 对于基本数据类型变量的原子性操作由JUC包原子类中的AtomicInteger等来实现;
    • 对于更大范围操作的原子性,使用 synchronizedLock 来实现。

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

    • volatile:当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值。
    • synchronizedLock:保证同一时刻只有一个线程获取锁然后执行同步代码,并且在释放锁之前会将对变量的修改刷新到主存当中,因此可以保证可见性。
    • final:被 final 关键字修饰的字段一旦初始化完成,并且没有发生 this 逃逸(其它线程通过 this 引用访问到初始化了一半的对象),也能保证对其他线程的可见性。

    有序性:程序执行的顺序按照代码的先后顺序执行。

    • 指令重排序:一般来说,处理器为了提高程序运行效率,可能会对输入代码进行优化,它不保证程序中各个语句的执行先后顺序同代码中的顺序一致,但是它会保证程序最终执行结果和代码顺序执行的结果是一致的(顺序不一致,但结果一致)。重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。

      源代码 -> 编译器优化的重排 -> 指令并行的重排 -> 内存系统的重排 ->最终执行的指令

    • 保证有序性的方法

      • volatile关键字
      • 通过synchronized和Lock来保证有序性,其可以保证每个时刻是有一个线程执行同步代码,相当于是让线程顺序执行同步代码,自然也就保证了有序性;
      • Java内存模型具备一些先天的“有序性”,即不需要通过任何手段就能够得到保证的有序性,通常称为happens-before原则。在JMM中,如果一个操作执行的结果需要对另一个操作可见,那么这两个操作之间必须要存在happens-before关系。这两个操作既可以在一个线程之内,也可以在不同线程之间。happens-before的一些重要规则:
        • 程序顺序规则:一个线程内,按照代码顺序,书写在前的操作线性发生于先行在后的操作;
        • 监视器锁规则:一个unlock操作先行发生于后面对同一个锁的lock操作;
        • volatile变量规则:对一个变量的写操作先行发生于后面对这个变量的读操作;
        • 传递性:若操作A先行发生于B,而操作B又先行发生于C,则可以得出操作A先行发生于C。
  • 相关阅读:
    RDIFramework.NET开发实例━表约束条件权限的使用-WinForm
    RDIFramework.NET V2.8版本 ━ 开发实例之产品管理(WinForm)
    RDIFramework.NET ━ Web中打印的各种方案参考-欢迎补充
    RDIFramework.NET 框架兼容各种数据库类型事务使用范例参考
    【干货】再上数据分页控件 ━ 更加灵活,更加实用-提供源码
    RDIFramework.NET ━ .NET快速信息化系统开发框架 V2.8 版本━新增岗位管理-Web部分
    RDIFramework.NET ━ .NET快速信息化系统开发框架 V2.8 版本━新增岗位管理-WinForm部分
    RDIFramework.NET ━ .NET快速信息化系统开发框架 V2.8 版本发布
    Javascript中的apply与call详解
    Javascript定义类(class)的三种方法
  • 原文地址:https://www.cnblogs.com/chiaki/p/13493899.html
Copyright © 2011-2022 走看看