文档章节

jvm - 内存模型与线程

i
 itititit
发布于 2017/08/25 10:12
字数 1047
阅读 11
收藏 0

JVM 通过定义内存模型来屏蔽各种硬件和操作系统的内存访问差异,以实现让java程序在各平台都能达到一致的内存访问效果。

工作内存可以类比为CPU中的高速缓存。

主内存与物理硬件的主内存类比。

内存间交互

8中操作都是原子的(除了long、doubley允许例外)。

  1. lock:作用于主存,标记线程独占。
  2. unlock:作用于主存,释放锁定的变量。
  3. read:作用于主存,将变量从主存读出,以便后续的load操作。
  4. load:作用于工作内存,将read读取的变量副本放入工作内存。
  5. use:作用于工作内存,将工作内存变量传给执行引擎。
  6. assign:将执行引擎的值赋给工作内存。
  7. store:作用于工作内存,从工作内存读出,传给主存,以便后续的write操作。
  8. write:作用于主存,将store的值保存到主存。

规定上述操作必须满足如下规定:

  1. 不允许read和load、store和write单独出现。
  2. 不允许丢弃assign操作,即变量在工作内存改变后必须将变化同步到主存。
  3. 不允许无原因地将数据从工作内存同步到主存(没有assign操作)。
  4. 变量智能在主存中产生。也就是说对变量实施use、store操作之前,必须先执行assign和load操作。
  5. 一个变量允许被同一个线程多次lock,但同时需要相同次数的unlock。
  6. 如果对一个变量进行lock操作,那么会清空工作内存此变量的值,执行引擎执行之前必须重新load或assign初始化值。
  7. 对变量进行unlock之前,必须有对应的lock。
  8. 对变量进行unlock之前,必须把变量同步回主存。

volatile

当一个变量定义为volatile后,具备两个特性,保证此变量对所有线程的可见性,这里的可见性指当一个线程改变了变量的值,新值对于其他程序是立即得知的。但并不是安全的,volatile变量也可以存在不一致的情况,但每次使用之前都要先刷新,执行引擎看不到不一致的情况,但是java的运算并不是原子操作(如++操作,对应多条字节码指令,每一条字节码指令有会对应多条机器指令)。

由于volatile只能保证可见性,所有不符合以下两条规则的场景下,仍然需要通过锁来保证。

  1. 运算结果不依赖变量的当前值,或者能确保只有一个线程修改变量的值。
  2. 变量不需要与其他的状态变量共同参与不变约束。

第二个特征是禁止指令重排序优化。

volatile变量在use之前必须有前置操作read和load操作。

assign之后必须立即有store和write操作。

volatile变量与普通变量的区别是:volatile保证新值能立即同步到主存,以及每次使用前立即从主存刷新。

先行发生

如果说操作A先行发生于B,就是说发生在操作B之前,操作A产生的影响能被操作B观察到。

一下是天然的先行发生关系,无需任何同步就已经存在:

程序次序:在一个线程内,书写在前面的操作先行发生于书写在后面的操作。

管程锁定:unlock操作先行发生于后面对同一锁的lock操作。

volatile:一个volatile的写操作先行发生于这个变量的读操作。

线程启动:Thread的start()先行发生此线程的每个动作。

线程中断:线程interrupt()方法的调用先行发生于被中断代码检测到中断事件的发生。

对象的终结:一个对象初始化完成(构造函数执行结束)先行发生于它的finalize()。

传递性:A先行发生B,B先行发生C,则A先行发生C。

 

 

 

 

 

 

© 著作权归作者所有

i
粉丝 0
博文 24
码字总数 15531
作品 0
私信 提问
JVM内存结构 VS Java内存模型 VS Java对象模型

Java作为一种面向对象的,跨平台语言,其对象、内存等一直是比较难的知识点。而且很多概念的名称看起来又那么相似,很多人会傻傻分不清楚。比如本文我们要讨论的JVM内存结构、Java内存模型和...

Java架构
2018/07/11
0
0
Java并发(1)- 聊聊Java内存模型

引言 在计算机系统的发展过程中,由于CPU的运算速度和计算机存储速度之间巨大的差距。为了解决CPU的运算速度和计算机存储速度之间巨大的差距,设计人员在CPU和计算机存储之间加入了高速缓存来...

knock_小新
2018/07/18
0
0
Java 10大优点—Part4—Java内存模型

在忙着参加在爱沙尼亚进行的 TEDx talk 演讲活动以及在比利时举办的一届非常忙碌的Devoxx 会议的间隙,我将继续推进 Java’s Rocking 的系列博文。 对还没有接触过这个系列博文的读者,不妨先...

foxlee
2013/12/09
400
1
JVM-----java内存区域与java内存模型

一.java内存区域 jvm在执行java程序的过程中会把所管理的内存分为若干不同的区域,有的区域随着虚拟机进程的启动而存在,有些区域则是依赖用户线程的启动和结束而建立和销毁的。 以下是java运...

Carol998
02/22
61
3
再有人问你Java内存模型是什么,就把这篇文章发给他!

前几天,发了一篇文章,介绍了一下JVM内存结构、Java内存模型以及Java对象模型之间的区别。有很多小伙伴反馈希望可以深入的讲解下每个知识点。Java内存模型,是这三个知识点当中最晦涩难懂的...

技术小能手
2018/09/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

rime设置为默认简体

转载 https://github.com/ModerRAS/ModerRAS.github.io/blob/master/_posts/2018-11-07-rime%E8%AE%BE%E7%BD%AE%E4%B8%BA%E9%BB%98%E8%AE%A4%E7%AE%80%E4%BD%93.md 写在开始 我的Arch Linux上......

zhenruyan
今天
5
0
简述TCP的流量控制与拥塞控制

1. TCP流量控制 流量控制就是让发送方的发送速率不要太快,要让接收方来的及接收。 原理是通过确认报文中窗口字段来控制发送方的发送速率,发送方的发送窗口大小不能超过接收方给出窗口大小。...

鏡花水月
今天
10
0
OSChina 周日乱弹 —— 别问,问就是没空

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @tom_tdhzz :#今日歌曲推荐# 分享容祖儿/彭羚的单曲《心淡》: 《心淡》- 容祖儿/彭羚 手机党少年们想听歌,请使劲儿戳(这里) @wqp0010 :周...

小小编辑
今天
1K
11
golang微服务框架go-micro 入门笔记2.1 micro工具之micro api

micro api micro 功能非常强大,本文将详细阐述micro api 命令行的功能 重要的事情说3次 本文全部代码https://idea.techidea8.com/open/idea.shtml?id=6 本文全部代码https://idea.techidea8....

非正式解决方案
今天
5
0
Spring Context 你真的懂了吗

今天介绍一下大家常见的一个单词 context 应该怎么去理解,正确的理解它有助于我们学习 spring 以及计算机系统中的其他知识。 1. context 是什么 我们经常在编程中见到 context 这个单词,当...

Java知其所以然
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部