Java内存模型(Memory Model)

Java内存模型(Memory Model)

  

  Java内存模型,Java Memory Model,我个人更喜欢“Java存储模型”的译法。

  介绍

  如前所述,JVM被设计成一台抽象的虚拟计算机,JVM的并发问题及解决方案与物理计算机中的并发问题有很多相似之处。

  由于现代计算机的内存与CPU在运算速度上的巨大差别,通常会加入一层更接近CPU读写速度的高速缓存(Cache),将运算使用到的数据复制到Cache中,让运算能加速进行,运算结束后再从Cache同步回内存之中。这个设计解决了速度的矛盾,也带来了一个新的问题:缓存一致性。在多CPU系统中,每个CPU都有自己的Cache,它们共享同一主内存,当多个CPU的运算任务涉及同一块内存区域时,就可能导致各自的Cache数据不一致。对此又设计了“缓存一致性协议”,如MESI,要求各个CPU在读写Cache时,都遵循这些协议进行操作,以解决缓存数据不一致的问题。“内存模型”(Memory Model),就是在特定的协议下,对特定的高速缓存读写访问过程进行抽象。不同架构的物理机器拥有不一样的内存模式,而Java虚拟机也有自己的内存模型,其基础原理是共通的。

  此外,为了充分利用CPU的运算单元,可能会对输入代码进行乱序执行优化,只保证执行结果的一致性,但不保证各语句的计算顺序与输入代码一致。Java虚拟机的即时编译器也有类似的指令重排序优化。

  Java语言规范中试图定义一种Java内存模型,以实现Java程序在各种平台上能达到一致的内存访问效果,为多线程的同步和避免数据争用提供一套有效平衡高吞吐与一致性的保障机制。

  什么是Java内存模型

  一个内存模型描述的是,给定程序的某个特定的执行轨迹(trace)是否是该程序的一个合法执行。Java内存模型检查执行轨迹中的每次读操作,以及根据特定规则,校验该读操作观察到的写是否合法。内存模型描述了一个程序的可预期行为,具体实现时拥有充分的自由度去生成需要的代码,只要其最终执行结果可经由内存模型进行推测。

  通俗地讲,Java内存模型(JMM)定义了一系列规则,以确保某一线程的写操作能正确呈现给其他线程。JMM并没有描述多线程该如何执行,而是描述多线程允许的行为。

  JMM规定了所有的共享变量都存储在JVM的主内存中。每条线程有自己的工作内存,用于保存该线程用到的变量的主内存副本拷贝(具体实现通常不会拷贝整个对象),线程对变量的操作全部在工作内存中进行,不能直接读写主内存中的变量。不同的线程间也无法直接访问对方的工作内存,线程间变量值的传递需要通过主内存来完成。

  关于主内存和工作内存之间的具体交互协议,即一个变量如何从主内存拷贝到工作内存、如何从工作内存同步回主内存之类的实现细节,JMM定义了8种操作(lock,unlock,read,load,use,assign,store,write),虚拟机实现时必须保证以上每一种操作都是原子的、不可再分的。

  共享变量/堆内存:能够在线程间共享的内存称作“共享内存或堆内存”。所有的实例域、静态域以及数组元素都存储在堆内存中。方法中的局部变量永远不会被线程间共享,也不会受内存模型影响。我们也无需关心线程内动作,每个单线程都应遵守正确的线程内语义。

  线程间的动作:线程间的动作是由某一线程执行,能被另一线程探测或直接影响的动作。包括:

  共享变量的读/写

  同步动作 (synchronization action)

  lock/unlock某个monitor;

  读写某个volatile变量

  启动一个线程

  与外部交互的动作

  导致某个线程进入无限循环的动作(thread devergence action)

  延伸阅读

  本文参考了《深入理解Java虚拟机》、《JSR-133-MemoryModel》,有充裕时间的同学可以去完整过一遍,但原文有较多艰涩难懂之处。这里做了较大的裁剪,隐藏更深一层的信息,以求对Java内存模型能有一个快速又不过于浅显的了解。更多的概念和规则:

  缓存一致性,Cache Coherence,MESI协议

  Instruction Reorder,指令重排序

  Happens-Before关系规则

  As-If-Serial ,线程内串行的语义

  Memory Barrier,内存屏障

  参考资料:

  JSR-133 Java Memory Model

  《Java语言规范SE8》第17章 线程与锁 17.4 内存模型

  《深入理解Java虚拟机》第12章 Java内存模型与线程

转载于:https://juejin.im/post/5bebcf1ff265da610e7fa454

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/101323.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • MOS管功率放大器电路图与原理图文及其解析[通俗易懂]

    MOS管功率放大器电路图与原理图文及其解析[通俗易懂]放大器电路的分类本文介绍MOS管功率放大器电路图,先来看看放大器电路的分类,按功率放大器电路中晶体管导通时间的不同可分:甲类功率放大器电路、乙类功率放大器电路和丙类功率放大器电路。甲类功率放大器电路,在信号全范围内均导通,非线性失真小,但输出功率和效率低,因此低频功率放大器电路中主要用乙类或甲乙类功率放大电路。功率放大器是根据信号的导通角分为A、B、AB、C和D类,我国亦称为甲、乙、甲乙、丙和丁类。功率放大器电路的特殊问题(1)放大器电路的功率功率放大器电路的任务是推动负载,因此功率放大电路的重

  • NIO Reactor模型

    NIO Reactor模型NIOReactor模型Reactor三种模型单线程模型多线程模型主从多线程模型Netty线程模型1线程组2ChannelPipeline3异步非阻塞Reactor模式是基于事件驱动开发的,服务端程序处理传入多路请求,并将它们同步分派给请求对应的处理线程,Reactor模式也叫Dispatcher模式,即I/O多路复用统一监听事件,收到事件后分发(Dispatch给某进程),这是编写高性能网络服务器的必备技术之一。Reactor模式以NIO为底层支持,核心组成部分包括Reactor和Ha

  • cpio制作initrd_正在生成initramfs

    cpio制作initrd_正在生成initramfs1、制作find.|cpio-o-Hnewc|gzip>../rootfs.cpio.gz2、解压zcatrootfs.cpio.gz|cpio-i-d-Hnewc–no-absolute-filename3、内核逻辑编译内核的时候会有一个GENinitramfs_data.cpio.gz如果有文件,就编译

  • 如何获取服务器种子_连接服务器超时代码leaf

    如何获取服务器种子_连接服务器超时代码leaf*{font-family:”微软雅黑”;}body{background:#fff;}input{cursor:pointer;}.ti{margin:0;padding:20px0;line-height:30px;color:#333;}.tia{color:#255359;}#trackertext{display:block;margin:0auto;backgroun…

  • 计算机组成原理总结及知识网图「建议收藏」

    计算机组成原理总结及知识网图「建议收藏」计算机组成原理知识摘要,个人复习整理,仅供参考

  • dwr a ajax 提交,ajax – Does Java offer a timestamp??…..DWR – Stack Overflow

    dwr a ajax 提交,ajax – Does Java offer a timestamp??…..DWR – Stack OverflowImusingDWR,whichimfairlynewto…IusingajaxtosubmitacommenttothepageandIgotrequesttoseeIficanshowatmestampwhenthecommentissubmitted:Inanutshell—Thebeanhasavaria…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号