zoukankan      html  css  js  c++  java
  • 聊聊JMM

    本文转载自聊聊JMM

    什么是JMM

    JMM (Java Memory Model )Java内存模型是一个语言级别的内存模型抽象,它屏蔽了底层硬件实现内存一致性需求的差异,提供了对上层的统一的接口来提供保证内存一致性的编程能力。

    Java作为一个跨平台的语言,Java内存模型作为一个中间层模型,它适配不同的底层硬件系统,设计一个中间层模型来屏蔽底层的硬件差异,给上层的开发者提供一个一致的使用接口,它为开发者屏蔽了底层的硬件实现细节,支持大部分的主流硬件平台。

    一致性模型

    任何语言编写出来的程序,最终都会转换为机器指令,按照一定的顺序去执行,所以在语言层面来讲,都是基于硬件层面提供的一致性模型基础上,来实现自身语言的功能和特性,如何保证语言层面的功能,在转换为硬件指令之后,根据语言的要求正确的运行,这就需要语言提供一种一致性模型的编程能力。Java内存模型就是java语言级别的内存模型抽象

    模型一致性

    模型一致性不止下面列的4种,根据概念的严格化,可以分为很多种,严格一致、顺序一致、因果一致等,在本文中我们只列4种,这4种对我们后期理解 Java内存模型有很大的帮助

    顺序一致性 Sequential Consistency

    也是常说的串行语义,它不要求全局的时钟顺序,只需要各个CPU局总的时钟顺序,

    对于每个CPU来说,它看到自己程序的执行顺序始终是和程序定义是一致的,

    从全局角度来看,相同的程序,在不同的CPU上运行,程序运行结果给人的感知顺序和是符合串行语义的,结果最终的视图是一致的

    弱一致性 Weak Consistency

    弱一致性是对被同步操保护的共享变量而言,系统中的某个数据被更新后,后续对该数据的读取操作可能得到更新后的值,也可能是更改前的值。它规定了只有对共享变量的同步操作完成之后,后续对该数据的读取都是更新后的值,同步操作这段时间被称为“不一致时间窗口”。

    释放一致性 Release Consistency

    弱一致性的粒度太大,包含了进入同步操作和释放同步操作两部分,而只有同步操作整体完成后,其他处理器才有可能保持一致性。 释放一致性规定了对同步变量的释放操作后,就对同步变量的状态广播到其他处理器,保证后续对该数据的读取都是更新后的值

    进入一致性 Entry Consistency

    和释放一致性一样,也是为了减小弱一致性的粒度,进入同步变量时,获取同步变量的最新状态,保证可以拿到数据更新后的最新值

    再看Java内存模型

    Java内存模型是一种比较松散的语言级内存模型,它通过加内存屏障(Memory Barrier),实现对共享数据的弱一致性、释放一致性、进入一致性的支持。

    最终语言是以机器指令在运行,JMM适配不同硬件平台,操作硬件指令,来提供一种语言层面满足一致性模型的编程能力,使开发者不需要关心代码是以什么顺序执行,只要能够正确的使用JMM提供的同步原语,就可以保证程序最终表现出来的行为是正确的。

    JMM适配了底层硬件,根据硬件指令提供一些同步原语,实现程序在多线程情况下的可见性,原子性、有序性,主要通过这些原语维护一套语言层面的运行规则 ,来保证语言层面的多线程下表现出来和串行语义一致的结果。

    JMM的这种一致性模型的编程能力,使程序员不需要关运行的代码在执行时候是乱成什么顺序,以什么顺序 执行,只要能够正确的使用JMM提供的同步原语,就可以保证程序最终表现出来的行为是正确的。

    主要功能就是屏蔽各硬件平台的差异,通过NATIVE方法,操作硬件指令组合,来实现JAVA中的语义,保证可见性,有序性,原子性。

    1. JMM提供的语义
    • 使用LOCK#信号、内存屏障实现语言层面的synchronized语义,保证复杂指令块的原子性 ,实现对共享变量的弱一致性保证
    • 对共享变量读之间插入加载屏障,在对共享变量写之后插入存储屏障,来实现volatile语义,实现对共享变量的释放一致性和进入一致性保证
    • 通过存储屏障,禁止初始化操作不重排到构造器结束之后,来实现final的语义
    1. 通过NATIVA方法屏蔽各硬件平台的差异

      不同的硬件底层实现的内存屏障方式不同

      不同硬件底层的硬件指令不同

    2. lazy write

    • 通过存储屏障,将写缓冲区中的数据写回主存,保证可见性和有序性
    • 通过加载屏障,清空无效化队列,保证可见性和有序性
    1. 禁止重排
    • 通过内存屏障,禁止指令重排,实现as-if -serial语义
    • 锁临界区的指令不允许逸出到临界区外
    • 内部锁的释放要在内部锁的申请之后执行
    • 线程中的任何操作都在start方法之后执行
    • 线程中的任何操作都在join方法之前执行
    • 同一个volatile变量读和写之间禁止重排

    结束

    文章的内容原于个人的理解,有可能和实际会有偏差,如果有发现请指正,以免误导他人。

    因为在JMM中大量提到了内存屏障,接下来准备写一篇关于内存屏障的文章

  • 相关阅读:
    火狐浏览器清理缓存快捷键
    SVN使用教程总结
    如何登陆服务器
    get、put、post、delete含义与区别
    zookeeper 半数可用/选举机制
    zookeeper 分布式安装/配置/启动
    lucene 统计单词次数(词频tf)并进行排序
    selenium 爬取空间说说
    MapReduce自定义InputFormat,RecordReader
    reduce 阶段遍历对象添加到ArrayList中的问题
  • 原文地址:https://www.cnblogs.com/yungyu16/p/13200633.html
Copyright © 2011-2022 走看看