概述

  由于计算机的运算速度和它的存储和通讯子系统的速度差距巨大,大部分时间都花在IO,网络和数据库上。为了压榨CPU的运算能力,需要并发。另外,优秀的并发程序对于提高服务器的TPS有重要的意义。

硬件的效率和一致性

  由于运算速度的差距,CPU和存储设备间加入多层的cache。同时也引入了缓存一致性的问题。解决缓存一致性有多种读写协议,(MSI,MESI,MOSI,Synapse,Firefly和Dragon Protocol等。

  为了使的处理器内部的运算单元能尽量被充分利用,处理器可能会对输入的代码进行乱序执行优化,处理器会在计算之后将乱序执行的结构重组,保证结果与顺序执行的结果是一致的,但不保证程序中各个语句计算的先后顺序与输入代码中的顺序一致。,因此存在一个计算任务依赖另一个计算任务的中间结果,那么其顺序不能依靠代码的先后顺序来保证。与处理器的乱序执行优化类似,java虚拟机的即时编译器中也有类似的指令重排序优化。

Java内存模型

  Java内存模型用来屏蔽掉各种硬件和操作系统的内存访问差异,已让java程序在各种平台都能达到一致的内存访问效果。Java内存模型的目标是定义程序中各个变量的刚问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节。

主内存与工作内存

  Java内存模型规定了变量(不含局部变量,因为局部变量线程私有,不存在共享问题)都得存放在主内存中,而每个线程对这些变量的操作都必须是从主内存中取出来并在工作内存中完成(如读取、写入的操作),不同线程之间不能访问对方的工作内存。如下图,展现了线程、主内存、工作内存之间的交互关系:


  加入一个工作内存的目的很明显,就是为了加快在内存中的操作数据的速度,因为工作内存优先存储在寄存器和高速缓存中,这两个操作的速度都远远快于主内存。主内存和工作内存之间交互的主要操作为:

  • Lock(锁定):作用于主内存的变量,将一个变量标示为一条线程独占的状态,其他线程不能访问。
  • Unlock(解锁):作用于主内存的变量,将一个处于锁定状态的变量释放出来,释放后的变量可以被其他线程锁定。
  • Read(读取):作用于主内存的变量,将一个变量的值从主内存传输到线程的工作内存,,以便进行load操作。
  • Load(加载):作用于工作内存中的变量,将read获取到的变量载入工作内存的变量副本中。
  • Use(使用):作用于工作内存中的变量,虚拟机执行引擎在执行字节码指令的时候,碰到了一个变量就会执行该操作,使用该变量。
  • Assgin(赋值):作用于工作内存中的变量,虚拟机执行引擎在执行字节码指令的时候,碰到了变量赋值的指令就会执行该操作。
  • Store(存储):作用于工作内存中的变量,将工作内存中的变量放入主内存,以便进行write操作。
  • Write(写入):作用于主内存中的变量,将store得到的变量放入主内存的变量中。

  JAva内存模型还规定了在执行上述8中操作时必须满足如下规则:

  • read 和load ,store和write 必须一对操作
  • 不允许线程丢弃assign操作,变量在工作内存中改变后必须把变化同步回主内存
  • 不允许一个线程无原因地没有发生过任何(assign操作)把数据从线程的工作内存同步回主存中
  • 新变量只能在主内存中诞生,不允许在工作内存中直接使用一个未被初始化的变量(load或assign),对一个变量实时use和store之前必须先执行过assign和load操作
  • 一个变量同一时刻值允许一条线程lock操作,但lock操作可以重复多次,执行相同数量的unlock,变量才会解锁
  • lock操作会清空工作内存副本,执行引擎使用前,需要执行load或者assign操作初始化变量的值
  • 没有lock操作,就不允许unlock操作。不允许unlock另一个线程变量。
  • unlock操作前必须先把此变量同步回主内存中(执行store,write操作)

  虚拟机允许将没有被volatile修饰的64位数据的读写操作划分为两次32位的操作来进行。

Happens-Before原则

  • 程序顺序规则:在一个线程内,按照程序代码顺序,书写在前面的操作先行发生于书写在后面的操作。
  • 管理锁定规则:一个unlock操作先于后面对同一个锁的lock操作。
  • Volatile变量规则:对一个volatile变量的写操作必须在对该变量的读操作之前发生。
  • 线程启动规则:线程的Thread.start()方法必须在该线程所有其他操作之前发生。
  • 线程终止规则:线程中所有操作都先行发生于该线程的终止检测。可以通过Thread.join()方法结束、Thread.isAlive()的返回值判断线程是否终止。
  • 线程中断规则:对线程interrupt()方法的调用必须在被中断线程的代码检测到interrupt调用之前执行。
  • 对象终结规则:对象的初始化(构造函数的调用)必须在该对象的finalize()方法完成。
  • 传递性:如果A先行发生于B,B先行发生于C,那么A先行发生于C。

关键概念

  并发,在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。

  并行:在操作系统中是指,一组程序按独立异步的速度执行,不等于时间上的重叠(同一个时刻发生)。

  多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。

  同步就是协同步调,按预定的先后次序进行运行。

  线程安全:当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或者协同,这几个类都能表现出正确的行为,那么就成这个类是线程安全的。

JAVA内存模型与线程的更多相关文章

  1. java内存模型与线程(转) good

    java内存模型与线程 参考 http://baike.baidu.com/view/8657411.htm http://developer.51cto.com/art/201309/410971_ ...

  2. Java并发程序设计(三) Java内存模型和线程安全

    Java内存模型和线程安全 一 .原子性 原子性是指一个操作是不可中断的.即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其它线程干扰. 思考:i++是原子操作吗?  二.有序性 Java代 ...

  3. 深入理解java虚拟机-第12章Java内存模型与线程

    第12章 Java内存模型与线程 Java内存模型  主内存与工作内存: java内存模型规定了所有的变量都在主内存中,每条线程还有自己的工作内存. 工作内存中保存了该线程使用的主内存副本拷贝,线程对 ...

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

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

  5. (Java多线程系列七)Java内存模型和线程的三大特性

    Java内存模型和线程的三大特性 多线程有三大特性:原子性.可见性.有序性 1.Java内存模型 Java内存模型(Java Memory Model ,JMM),决定一个线程对共享变量的写入时,能对 ...

  6. 深入理解Java虚拟机(第三版)-13.Java内存模型与线程

    13.Java内存模型与线程 1.Java内存模型 Java 内存模型的主要目的是定义程序中各种变量的访问规则,即关注在虚拟机中把变量值存储到主内存和从内存中取出变量值的底层细节 该变量指的是 实例字 ...

  7. 一夜搞懂 | Java 内存模型与线程

    前言 本文已经收录到我的 Github 个人博客,欢迎大佬们光临寒舍: 我的 GIthub 博客 学习导图 一.为什么要学习内存模型与线程? 并发处理的广泛应用是 Amdah1 定律代替摩尔定律成为计 ...

  8. Java内存模型与线程(一)

    Java内存模型与线程 TPS:衡量一个服务性能的标准,每秒事务处理的总数,表示一秒内服务端平均能够响应的总数,TPS又和并发能力密切相关. 在聊JMM(Java内存模型)之前,先说一下Java为什么 ...

  9. 《深入了解java虚拟机》高效并发读书笔记——Java内存模型,线程,线程安全 与锁优化

    <深入了解java虚拟机>高效并发读书笔记--Java内存模型,线程,线程安全 与锁优化 本文主要参考<深入了解java虚拟机>高效并发章节 关于锁升级,偏向锁,轻量级锁参考& ...

  10. java内存模型和线程

    概述 多任务的处理在现在的计算机中可以说是"标配"了,在许多的情况下,让计算机同时做几件事情,不仅是因为计算机的运算能力的强大,还有一个重要的原因是:cpu的运算速度和计算机的存储 ...

随机推荐

  1. 参加光环国际PRINCE2培训

    挑战埃及是全球首套能够同时适配PRINCE2认证人群,PMP认证人群的项目管理沙盘演练游戏.沙盘通过使用乐高积木作为道具,通过一场互动性极强的情景模拟为全球项目经理还原了四千年前古埃及金字塔建造的情景 ...

  2. STM32位带操作总结---浅显易懂

    正在准备做毕业设计,配置LED_Config()的时候,又看到了位带操作的宏定义,我又嘀咕了,什么是位带操作,一年前在使用位带操作的时候,就查阅过好多资料,Core-M3也看过,但是对于博主这种“低能 ...

  3. 老李分享:Eclipse中开发性能测试loadrunner脚本

    老李分享:Eclipse中开发性能测试loadrunner脚本 前篇我分享了如何用loadrunner搭建javauser的性能测试脚本环境,本次我来告诉大家如何在eclipse开发loadrunne ...

  4. js实现多行图片点击(自动)左右无缝轮播特效

    /*效果图*/ HTML:    <div class="scroll">       <div class="picbox">     ...

  5. 原型prototype、原型链__proto__、构造器constructor

    创建函数时,会有原型prototype,有原型链__proto__,有constructor.(构造函数除外,没有原型) . prototype原型:是对象的一个属性(也是对象),使你有能力向对象添加 ...

  6. 《连载 | 物联网框架ServerSuperIO教程》- 18.集成OPC Client,及使用步骤

    1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...

  7. form表单的enctype

    form表单在你不写enctype属性时,也默认为其添加了enctype属性值,默认值是enctype="application/x- www-form-urlencoded".这 ...

  8. 初识bd时的一些技能小贴士

    既然小豆腐如此给力,而且充分的利用主动学习的优势,已经有了迅速脑补,压倒式的优势,不过这只是表面而已,一切才刚刚开始,究竟鹿死谁手,还有待验证. 以上可以看到,小豆腐为什么拼命的要teach我们了么, ...

  9. 【转载】rem自适应布局-移动端自适应必备

    原文链接:rem自适应布局-移动端自适应必备 版权所有,转载时请注明出处,违者必究. 由于移动端特殊性,本文讲的是如何使用rem实现自适应,或叫rem响应式布局,通过使用一个脚本就可以rem自适应,不 ...

  10. Dubbo的使用简介

    Dubbo是什么 官方定义 DUBBO是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,是阿里巴巴SOA服务化治理方案的核心框架,每天为2,000+个服务提供3,000,000, ...