JVM-并发-Java 内存模型
Java内存模型
(1). 主内存与工作内存
Java内存模型规定了所有的变量都存储在主内存中.
每类线程的变量的主内存副本拷贝,线程对变量的所有操作(读操作,赋值操作等)都必须工作内存中进行,而不能直接读写主内存中的变量.
不同的线程之间无法直接访问对方工作内存中的变量,线程间变量的传递均需要通过主内存来完成.
(2)内存之间额操作
主内存与工作内存交互,Java内存模型定义了8种操作来完成.
a)lock(锁定):作用于主内存的变量,它把一个变量标识为一条线性独占的状态.
b)ublock(解锁):作用于主内存的变量,它把一个处于锁状态的变量释放出来,释放后的变量才可以被其他线程锁定.
c)read(读取):作用于主内存的变量,它把一个变量的值从主内存传输到线程的内存中,以便随后的load动作使用.
d)load(载入):作用于内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中.
e)use(使用):作用于工作内存中的变量,它把工作内存中的一个变量的值传递给执行引擎,每当虚拟机遇到一个需要使用变量的值的字节码指令时将会执行这个操作.
f)assign(赋值):作用于工作内存中的变量,它把一个执行引擎接收到的值赋值给工作内存的变量,每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作.
g)store(存储):作用于工作内存的变量,它把工作内存中一个变量的值传递到主内存中,以便随后的write操作使用.
h)write(写入):作用于主内存的变量,它把store操作从工作内存中得到的变量的值放入到主内存的变量中.
(3)Java内存模型规定了在执行上述8种基本操作时必须满足如下规则:
a) 不允许read和load,store和write操作之一单独出现,既不允许一个变量从主存读取了但是工作内存发起回写不接受的情况出现
b) 不允许一个线程丢弃它的最近的assign操作,即变量在工作内存中改变了之后必须把变量同步到主内存
c) 不允许一个线程无原因(没有发生过任何assign操作)把数据从线程的工作内存同步会主内存
d) 一个新的变量只能在主内存中“诞生”,不允许在工作内存中直接使用一个未被初始化的变量,换句话说就是 对一个变量实施use,store操作之前,必须执行过了assign和load操作
e) 一个人变量在同一时刻只允许一条线程对其进行lock操作可以被同一条线程重复执行多次,多次执行lock后,只有执行相同德尔unlock操作,变量才会被解锁
f) 如果一个变量执行lock操作,那将会清空工作内存中此变量的值,在执行引擎使用这个变量前,需要重新执行load或assign操作初始化变量的值
g) 如果一个变量事先没有被lock操作锁定,那就不允许对它执行unlock操作,也不允许unlock一个被其他线程锁定的变量
h) 对一个变量执行unlock操作之前,必须先把此变量同步会煮主内存(执行store,write操作)
(4)对于volatile型变量的特殊规则:
a) 只能保证可见性
b) 禁止指令重排序优化
(5)对long和double型变量的特殊规则:
a) Java内存模型规定:允许虚拟机将没有被volatile修饰的64位数据的读写操作划分为两次32位操作进行,及允许虚拟机实现选择可以不保证64位数据类型的load,store,read和write这4个操作的原子性。这就是long和double的非原子性协定
(6)原子性、可见性与有序性
原子性:由Java内存模型来直接保证的原子性变量操作包括read,load,assign,use,store和write
可见性:指当一个线程修改了共享变量的值,其他线程能够立即得知这个修改
有序性:如果在本线程内观察,所有的操作都是有序的,如果在一个线程中观察另一个线程,所有的操作都是无序的
(7)先行发生原则
先行发生时Java内存模型中定义的两项操作之间的关系,如果说操作A先行发生于操作B,其实就是在发生操作B之前,操作A产生的影响能够被操作B观察到。“影响”包括修改了内存中共享变量的值,发送了消息,调用了方法等。
程序次序规则:在一个线程内,按照程序代码顺序,书写在前面的操作先于发生在书写在后面的操作。准确的说,应该是控制流顺序而不是程序代码顺序,因为要考虑分支、循环等结构。
管程锁定规则:一个unlock操作先行发生于后面对同一个锁的lock操作。
volatile变量规则:对一个volatile变量的写操作先行发生于后面对这个变量的读操作,这里的“后面”是指时间上的先后顺序
线程启动规则:Thread对象的start方法先行发生于此线程的每一个动作
线程终止规则:线程中的所有操作都先于此线程的终止检测,我们可以通过Thread.join()方法结束。THread.Alive()的返回值等手段检到线程已经终止执行
线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生,可以通过Thread.interrupted()方法检测到是否有中断发生
对象终结规则:一个对象的初始化完成(构造函数执行结束)先行发生于它的finalize()方法的开始
传递性:如果操作A先行发生于操作B,操作B先行发生于操作C,那就得出操作A先行发生于操作C的结论
JVM-并发-Java 内存模型的更多相关文章
- 【JVM】Java内存模型
原文:多线程之Java内存模型(JMM)(一) 概述 多任务和高并发是衡量一台计算机处理器的能力重要指标之一.一般衡量一个服务器性能的高低好坏,使用每秒事务处理数(Transactions Per S ...
- jvm(12)-java内存模型与线程
[0]README 0.1)本文部分文字描述转自“深入理解jvm”,旨在学习“java内存模型与线程” 的基础知识: [1]概述 1)并发处理的广泛应用是使得 Amdahl 定律代替摩尔定律称为计 ...
- 我要学并发-Java内存模型到底是什么
内存模型 在计算机CPU,内存,IO三者之间速度差异,为了提高系统性能,对这三者速度进行平衡. CPU 增加了缓存,以均衡与内存的速度差异: 操作系统增加了进程.线程,以分时复用 CPU,进而均衡 C ...
- Java并发-Java内存模型(JMM)
先来说说什么是内存模型吧 在硬件中,由于CPU的速度高于内存,所以对于数据读写来说会出现瓶颈,无法充分利用CPU的速度,因此在二者之间加入了一个缓冲设备,高速缓冲寄存器,通过它来实现内存与CPU的数据 ...
- 深入理解JVM(6)——Java内存模型和线程
Java虚拟机规范中定义了Java内存模型(Java Memory Model,JMM)用来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果(“即Ja ...
- JVM(7) Java内存模型与线程
衡量一个服务性能的高低好坏,每秒事务处理数(Transactions Per Second,TPS)是最重要的指标之一,它代表着一秒内服务端平均能响应的请求总数,而 TPS 值与程序的并发能力又有非常 ...
- JVM总结-java内存模型
我们先来看一个反常识的例子. int a=0, b=0; public void method1() { int r2 = a; b = 1; } public void method2() { in ...
- 理解JVM之java内存模型
java虚拟机规范中试图定义一种java内存模型(JMM)来屏蔽掉各种硬件和操作系统内存访问差异,以实现让java程序在各种平台都能打到一致的内存访问效果.所以java内存模型的主要目标是定义程序中各 ...
- Java高并发-Java内存模型和线程安全
一.原子性 原子性是指一个操作是不可中断的.即使在多个线程一起执行的时候,一个操作一旦开始,就不会被其它线程干扰. i++是原子操作吗? 不是,包含3个操作:读i,i=i+1,写i 32位的机子上读取 ...
- Java并发编程(四)-- Java内存模型
Java内存模型 前面讲到了Java线程之间的通信采用的是共享内存模型,这里提到的共享内存模型指的就是Java内存模型(简称JMM),JMM决定一个线程对共享变量的写入何时对另一个线程可见.从抽象的角 ...
随机推荐
- 较全的IT方面帮助文档
http://www.shouce.ren/post/d/id/108632 XSLT参考手册-新.CHMhttp://www.shouce.ren/post/d/id/108633 XSL-FO参考 ...
- Moving Tables(贪心或Dp POJ1083)
Moving Tables Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 28304 Accepted: 9446 De ...
- Unity-The Courtyard demo学习
1.编辑器相机同步 The Courtyard的demo中,会发现Scene视图和Game视图是编辑器下同步的,它通过一个CopySceneView.cs脚本实现 Scene视图和Game视图的显示效 ...
- asp.net core 通过 TeamCity 实现持续集成笔记
0x00 很早之前就想体验一把持续集成的快感,然后刚好手头上有个 asp.net core 的项目,就想来部署一下持续集成.一开始我是想用 Jenkins 的,弄了好半天,git 仓库没法同步下来,我 ...
- IntelliJ IDEA 14和Maven创建java web项目
安装Maven 下载安装 去maven官网下载最新版. 解压到安装目录. 配置 右键桌面的计算机图标,属性–>高级系统设置–>环境变量,添加M2_HOME的环境变量,然后将该变量加入的PA ...
- selenium—JS点击方法
package com.allin.pc;import java.util.NoSuchElementException;import org.openqa.selenium.By;import or ...
- wifipineapple使用教程
1.把开关拨到右边 如果有灯亮说明有电 4个灯全亮说明电量是满的 以此类推 如果一个也不亮说明没电了需要用充电器充电 2.把开关拨到左边打开wifi的开关 会开启一个wifi大概一分钟左右会有wif ...
- jquery之empty()方法详解
empty()函数用于清空每个匹配元素内的所有内容. empty()函数将会移除每个匹配元素的所有子节点(包括文本节点.注释节点等所有类型的节点). 该函数属于jQuery对象(实例). 语法 jQu ...
- iOS应用性能调优建议
本文来自iOS Tutorial Team 的 Marcelo Fabri,他是Movile的一名 iOS 程序员.这是他的个人网站:http://www.marcelofabri.com/,你还可以 ...
- 避免jsp传参返回乱码问题
$("#searchForm input").each(function(i){ var obj=$(this); var va=obj.val(); obj.val(decode ...