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. javascript编程: JSON, Mapping, 回调

    使用 Javascript  编程, 组合使用 JSON 数据格式,Mapping 和回调技术, 可以产生很强的表达效果. 在实际工作中, 总会有数据汇总的需求. 比如说, 取得了多个 device ...

  2. 混合使用 ForkJoin, Akka, Future 实现一千万个不重复整数的排序

    定位  本文适合于想要了解新语言 Scala 以及异步并发编程框架 Akka, Future 的筒鞋. 读完本文后,将了解如何使用 ForkJoin 框架.如何使用 Akka 构建并发程序.如何使用 ...

  3. JAVA下的Thread.sleep方法一定要try

    try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } 不同于C#,JAVA里的Thre ...

  4. Java基础 静态块、非静态块、构造函数的执行顺序

    Java中经常有一些静态块,这是用来在生成类之前进行的初始化,无论java还C++语言中的static,都是最先初始化好的.结构如下: static { 静态语句代码块 } { 非静态语句代码块 }  ...

  5. ie11媒体查询以及其他hack

    <!doctype html> <html> <head> <title>IE10/11 Media Query Test</title> ...

  6. HDU 5688:2016"百度之星" - 资格赛 Problem D

    原文链接:https://www.dreamwings.cn/hdu5688/2650.html Problem D Time Limit: 2000/1000 MS (Java/Others)    ...

  7. 【20160924】GOCVHelper MFC增强算法(4)

    //string替换     void string_replace(string & strBig, const string & strsrc, const string & ...

  8. logging模块转载博客

     转载自:http://blog.csdn.net/zyz511919766/article/details/25136485 简单将日志打印到屏幕: [python] view plain copy ...

  9. [书]WALL·E、龙与地下铁、中国美丽的故事、故事新编、四十自述、书虫、人工智能、大话数据结构

    下午有时间,逛了逛了书城,看到了一些书.在这里总结一些自己的感受.   一.<龙与地下铁>     这本书是我首先看到的,就在靠前的新书区.是小说,我没看里面的内容,但是被书封皮的宣传文案 ...

  10. R----stringr包介绍学习

    1. stringr介绍 stringr包被定义为一致的.简单易用的字符串工具集.所有的函数和参数定义都具有一致性,比如,用相同的方法进行NA处理和0长度的向量处理. 字符串处理虽然不是R语言中最主要 ...