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 内存模型的更多相关文章

  1. 【JVM】Java内存模型

    原文:多线程之Java内存模型(JMM)(一) 概述 多任务和高并发是衡量一台计算机处理器的能力重要指标之一.一般衡量一个服务器性能的高低好坏,使用每秒事务处理数(Transactions Per S ...

  2. jvm(12)-java内存模型与线程

    [0]README 0.1)本文部分文字描述转自“深入理解jvm”,旨在学习“java内存模型与线程” 的基础知识:   [1]概述 1)并发处理的广泛应用是使得 Amdahl 定律代替摩尔定律称为计 ...

  3. 我要学并发-Java内存模型到底是什么

    内存模型 在计算机CPU,内存,IO三者之间速度差异,为了提高系统性能,对这三者速度进行平衡. CPU 增加了缓存,以均衡与内存的速度差异: 操作系统增加了进程.线程,以分时复用 CPU,进而均衡 C ...

  4. Java并发-Java内存模型(JMM)

    先来说说什么是内存模型吧 在硬件中,由于CPU的速度高于内存,所以对于数据读写来说会出现瓶颈,无法充分利用CPU的速度,因此在二者之间加入了一个缓冲设备,高速缓冲寄存器,通过它来实现内存与CPU的数据 ...

  5. 深入理解JVM(6)——Java内存模型和线程

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

  6. JVM(7) Java内存模型与线程

    衡量一个服务性能的高低好坏,每秒事务处理数(Transactions Per Second,TPS)是最重要的指标之一,它代表着一秒内服务端平均能响应的请求总数,而 TPS 值与程序的并发能力又有非常 ...

  7. JVM总结-java内存模型

    我们先来看一个反常识的例子. int a=0, b=0; public void method1() { int r2 = a; b = 1; } public void method2() { in ...

  8. 理解JVM之java内存模型

    java虚拟机规范中试图定义一种java内存模型(JMM)来屏蔽掉各种硬件和操作系统内存访问差异,以实现让java程序在各种平台都能打到一致的内存访问效果.所以java内存模型的主要目标是定义程序中各 ...

  9. Java高并发-Java内存模型和线程安全

    一.原子性 原子性是指一个操作是不可中断的.即使在多个线程一起执行的时候,一个操作一旦开始,就不会被其它线程干扰. i++是原子操作吗? 不是,包含3个操作:读i,i=i+1,写i 32位的机子上读取 ...

  10. Java并发编程(四)-- Java内存模型

    Java内存模型 前面讲到了Java线程之间的通信采用的是共享内存模型,这里提到的共享内存模型指的就是Java内存模型(简称JMM),JMM决定一个线程对共享变量的写入何时对另一个线程可见.从抽象的角 ...

随机推荐

  1. Linux+I2C总线分析(主要是probe的方式)

    Linux I2C 总线浅析 ㈠ Overview Linux的I2C体系结构分为3个组成部分: ·I2C核心: I2C核心提供了I2C总线驱动和设备驱动的注册.注销方法,I2C通信方法(即“algo ...

  2. sftp 设置仅能访问自己目录的用户

    1. 创建一个目录,owner为root,权限为750或755,此处为 /home/test01 添加一个用户test01,home目录设置为 /home/test01 再创建一个子目录用于用户上传: ...

  3. Android 自动化测试 Emmagee

    Emmagee 是一个性能测试小工具 用来监控指定被测应用在使用过程中占用机器的CPU, 内存,流量资源的性能小工具 阅读目录 Emmagee 介绍 Emmagee是网易杭州研究院QA团队开发的一个简 ...

  4. 微信小程序配置文件

    app.json   配置文件中不能有注释 { "pages": [ // 必填 设置页面路径 "pages/index/index", "pages ...

  5. 通过HWND获得CWnd指针

    cwnd 又为计算机网络中拥塞窗口(congestion window)的简写.拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化.发送方让自己的发送窗口还可能小于拥塞窗口. CWnd是MFC窗口类 ...

  6. HMI开发与控件

    =>控件是什么概念? 百度曰,控件是对数据和方法的封装.控件可以有自己的属性和方法.属性是控件数据的简单访问者. 对于HMI开发来说,使用控件可以快速获取到用户的交互(包括按下.释放.点击.拖动 ...

  7. 用excel做差异表达

    首先准备数据:表达矩阵 ACC.uncv2.mRNAseq_RSEM_normalized_log2.txt(以下载的TCGA的数据,log之后的) 上面数据中01为tumor,11为normal 我 ...

  8. Android Activity的加载模式和onActivityResult方法之间的冲突

    前言 今天在调试程序时,发现在某一Activity上点击返回键会调用该Activity的onActivityResult()方法.我一开始用log,后来用断点跟踪调试半天,还是百思不得其解.因为之前其 ...

  9. PHP 小方法之 显示 今天 昨天 上周 上月 近三月 的时间

    if(!function_exists('get_date_array')){ function get_date_array(){ $_NOW = time(); $today_begin = st ...

  10. C#连接数据库的新方法(通过web.config配置文件)

    分类: asp.net技术 2009-07-08 19:40 183人阅读 评论(0) 收藏 举报 方法一.   1.web.config中<configuration>下加入以下连接代码 ...