1.概述

  高效并发通过JAVA线程之间提高并发协调实现,在实现过程中需考虑硬件的效率和一致性,但在运算的过程中需要考虑处理器与内存的交互,所以基于高速缓存的存储交互解决的处理器与内存的方案,在对多处理器系统中,共享着同一内存,所以JAVA中也提出了JMM的概念,JMM可以理解为特定的操作协议中,对特定的内存或高速缓存进行读写访问的过程抽象,不同的物理机器拥有不同的内存模型,JVM也有自己的内存模型,在以高速缓存的前提下,处理器对输入代码进行乱序执行(Out-Of-Order Execution)优化,通过处理器计算之后的乱序结果重组,保证结果与顺序执行一致,JVM也有类似的"指令重排序"优化。

2.JMM

   JMM被定义为用来屏蔽各种硬件和操作系统的内存访问差异,以实现JAVA各个平台达到一致的内存访问效果,在这之前主流程序语言直接使用物理硬件和操作系统的内存模型,这会导致处理器和内存存在着差异,针对这一情况,在JDK1.5(JSR-133),JMM开始被完善.

   JMM的目标是定义程序中变量的访问规则,在虚拟机中将变量存储到内存和从内存中取出变量,包括实例字段,静态字段和构成数组,但不包括局部变量和方法参数,因为是线程私有的,不会被共享,JMM规定了所有变量都存储在”主内存“,每条线程都有自己的"工作内存",变量的所有操作都在工作内存中进行,而不是读写足内存的变量,不同的线程之间无法直接访问对方的工作内存中的变量

3.内存交互操作

   主内存和工作内存之间有具体的交互协议,JMM定义了以下8中操作来完成,虚拟机实现时必须保证每一种操作都是原子的,不可再分的.

    1.lock 作用于主内存的变量,把一个标量标识为一条线程独占的状态

    2.unlock作用于主内存的变量,把一个处于锁定状态的变量释放出来,被释放的变量可以被其它线程锁定

    3.read作用于主内存的变量,把一个变量的值从主内存传输到相册过的线程工作内存,以便随后的LOAD操作

    4.load作用与工作内存的变量,把read操作从主内存得到的变量放入工作内存的变量副本

    5.use 作用于工作内存变量,把工作内存的变量传递给执行引擎,每当虚拟机遇到一个需要使用的变量的值的字节码指令时会执行这个操作

    6.assign 作用于工作内存的变量,把一个从执行引擎接收到的值赋给工作内存的变量,每当虚拟机遇到一个给变量赋值的字节指令码指令时执行这个操作

    7.store 作用与工作内存的变量,把工作内存中的一个变量值传递到主内存中,以便write操作

    8.write 作用与工作内存的变量,把store操作从工作内存中得到的值放入主内存的变量

  在一个变量从主内存复制到工作内存中,JMM规定RL操作和SW操作必须按顺序执行,但没有保证连续执行,但在基本操作中必须满足以下规则

  1.不允许RL,SW操作之一单独出现,不允许一个变量从主内存读取了但工作内存不接受

  2.不允许一个线程丢弃他最近的assign操作,变量在工作内存中改变了之后必须把该变化同步回主内存

  3.不允许一个线程无原因把数据从线程的工作内存同步回主内存中.

  4.一个新的变量只能在主内存中诞生,不允许在工作内存直接使用使用一个未被初始化的变量.

  5.一个变量在同一时刻只允许一条线程执行lock操作。

  6.对一个变量执行lock操作,将会清空工作内存中的变量的值

  7.一个变量事先没有被lock锁定,那就不允许对他执行unlock操作

  8.对一个变量执行unlock操作之前,必须先把此变量同步到主内存中

  

Volatile变量的特殊规则

  当一个变量被定义为volatile时,具备两个特性

  1.保证变量对所有线程的可见性,指一条线程修改了这个变量的值,新的值被其它线程可以得知,普通变量的值在线层之间传递需要足内存来完成,

  由于volatile变量只能保持可见性,在不符合两条规则的运算场景中,仍然需要通过加锁来保证(synchronized或java.util.concurrent)原子性

  1.运算结果并不依赖变量的当前值,或者只有单一的线程修改变量的值

  2.变量不需要与其他的状态变量共同参与不变约束

longdouble变量规则

 JMM定义了允许虚拟机可以选择不保证64位LOAD,STORE,READ,WRITE的原子性,如果多个线程共享一个VOLATILE的long或者double变量,并且同时对他们进行读取的修改操作,那么某个线程会获得一个非原值,而不是其它线程修改的变量

  

原子性可见性和有序性

  JMM围绕着并发过程中的原子性可见性和有序性来建立

  原子性(Actonicity) JMM来保证原子性变量操作,基本类型的访问读写具有原子性

  可见性(Visibility)可见性只当一个线程修改了共享变量的值,其它线程能够立即得到资格修改,java中通过synchronized 和final来实现可见性,同步块的可见性是由一个“变量执行unlock操作之前”,必须先把此变量同步回主内存中这条规则获取,final关键字的可见性是指,在构造器一旦初始化完成,并且构造器没有把"this"的引用传递过去,那在其它线程中看到final字段的值.

  有序性(Ordering)指的是如果在本线程内观察,所有的操作都是有序的,如果在一个线程观察另一个线程,所有操作都是无序的,前半句是指"线程内表现为串行的语义",后半句指的是指令重排序.

  JAVA提供volatile和synchronized来确保线程操作之间的有序性,volatile包含了禁止指令重排序的语义,而synchronized是由"一个变量在同一时刻只允许对一个线程进行lock操作"

先行发生原则(happens-before)

  JAVA总有一个happens-before原则,用于判断是否存在竞争,线程是否安全的依据,H-B原则在JMM定义为两项操作的偏序关系,在JMM中存在着天然的H-B原则

  1.程序次序规则:在一个线程内,按照程序代码顺序,书写在前面的操作先行发生于书写在后面的操作.

  2.管程锁定原则:一个unlock操作先行于发生于后面同一个锁的lock操作

  3.volatile变量规则:对一个volatile变量的写操作相信发生于后面对这个变量的读操作.

  4.线程启动规则:Thread对象的start()方法先行发生于线程的每一个操作

  5.线程终止规则:通过Thread().join()方法结束,Thread.isAlive()的返回值手段检测线程中止执行

  6.中断规则:一个对象的初始化完成先行发生于他的finalize()方法开始

  7.传递性:A-B B-C ==A-C

JAVA线程

  用户实现线程主要有3个方式:内核线程实现,内核线程和用户线程加轻量级进程混合实现

1.内核线程

  KLT有操作系统内核(kernel)实现,由内核完成线程转换,内核通过操纵调度器对线程进行调度,并负责将线程的任务映射到各个处理器上,每个内核内核线程可以视为一个内核分身,但程序一般不会直接使用内核线程,而是使用内核线程的一种高级接口--轻量级进程(LWP),只有支持内核线程,才能有轻量级线程,以下是关系图

有内核线程的支持,每一个轻量级进程都会成为一个独立的调度单元,即使有一个轻量级进程堵塞,也不会影响工作

2.用户线程

  一个线程只要不是内核线程,就可以认为是用户线程,轻量级线程可以认为是用户线程,用户线程的优势在于不出要系统内核支援,劣势也在于没有系统内核的支援,所有线程操作都需要用户自己处理,这对程序有不利的因素,存在着1:N的关系所以不推荐使用.

3.使用用户线程加轻量级进程混合实现

  混合实现情况下,即存在用户线程也存在轻量级进程,在创建过程中通过内核的线程调度以及处理器映射,对用户线程通过轻量级进程完成,降低了进程阻塞的风险。存在着N:M的关系

线程调度

  线程调度值系统为线程分配处理器使用权的过程,分为协同式系统调度(Cooperative Threads-Scheduling)和抢占式线程调度(Preemptive Threads-Scheduling)

1.协同式系统调度执行时间由线程本身来控制,好处在于实现简单,而且线程是要把事情刚完才会线程切换,切换操作时线程可知的,所以不会担心进程阻塞问题,线程控制时间不可控制,甚至一个线程编写有问题,一直不告知系统进行线程切换,那么线程会阻塞在这里.。

 2.抢占式调度线程由系统分配执行时间,线程的切换不由系统本身。

线程切换

  1.新建

  2.运行

  3.无限期等待

    3.1没有设置TimeOut参数的Object.wait()方法

    3.2没有设置TimeOut参数的Thread.join()方法

  4.限期等待(TIME WAITING)

    4.1Thread.sleep()方法

    4.2Object.Wait()

    4.3Thread.join()

    4.4LockSupport.ParkNanos()

    4.5LockSupport.parkUtil()

  5.阻塞

    阻塞状态在等待着获取到一个排它锁,等待状态则在等待一段时间或者唤醒动作的发生,在程序等待进入同步区域时,线程将进入这个状态

  6.结束

    终止线程的线程状态

  

  

  

JMM&Thread的更多相关文章

  1. 浅析java内存模型--JMM(Java Memory Model)

    在并发编程中,多个线程之间采取什么机制进行通信(信息交换),什么机制进行数据的同步? 在Java语言中,采用的是共享内存模型来实现多线程之间的信息交换和数据同步的. 线程之间通过共享程序公共的状态,通 ...

  2. JMM(java内存模型)

    What is a memory model, anyway? In multiprocessorsystems, processors generally have one or more laye ...

  3. JMM和happens-before原则

    JMM: Java Memory Model(Java内存模型),围绕着在并发过程中如何处理可见性.原子性.有序性这三个特性而建立的模型. 可见性: JMM提供了volatile变量定义.final. ...

  4. Java多线程 -- 深入理解JMM(Java内存模型) --(五)锁

    锁的释放-获取建立的happens before 关系 锁是Java并发编程中最重要的同步机制.锁除了让临界区互斥执行外,还可以让释放锁的线程向获取同一个锁的线程发送消息. 下面是锁释放-获取的示例代 ...

  5. Java内存模型JMM与可见性

    Java内存模型JMM与可见性 标签(空格分隔): java 1 何为JMM JMM:通俗地讲,就是描述Java中各种变量(线程共享变量)的访问规则,以及在JVM中将变量存储到内存和从内存中读取变量这 ...

  6. 从一个简单的Java单例示例谈谈并发 JMM JUC

    原文: http://www.open-open.com/lib/view/open1462871898428.html 一个简单的单例示例 单例模式可能是大家经常接触和使用的一个设计模式,你可能会这 ...

  7. The JSR-133 Cookbook for Compiler Writers(an unofficial guide to implementing the new JMM)

    The JSR-133 Cookbook for Compiler Writers by Doug Lea, with help from members of the JMM mailing lis ...

  8. JMM内存管理

    原文地址http://www.cnblogs.com/BangQ/p/4045954.html 原本准备把内存模型单独放到某一篇文章的某个章节里面讲解,后来查阅了国外很多文档才发现其实JVM内存模型的 ...

  9. J.U.C JMM. pipeline.指令重排序,happen-before(续)

    前面已经介绍硬件平台Cache Coherence问题和解决办法,下面来看看Java虚拟机平台的相关知识.硬件平台处理器,高速缓存,主存之间的交互关系如下: Java内存模型(JMM)         ...

随机推荐

  1. SGU 107 987654321 problem【找规律】

    题目链接: http://acm.sgu.ru/problem.php?contest=0&problem=107 题意: 平方后几位为987654321的n位数有多少个 分析: 虽然说是水题 ...

  2. myeclipse2013在线安装svn

    之前安装svn一直不行.弄了好久.还是在线安装方便. 在Help里面点击Install from Site,然后直接图解: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkb ...

  3. [asp.net]登录协同工作平台安全解决方式

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/david_520042/article/details/25372207 [摘要]公司领导说登录验证 ...

  4. this 、静态变量

    /*作者:qingfeng日期:2017/2/18功能:this,静态变量(类变量)*/class Demo3_2{    public static void main(String args[]) ...

  5. HDU_1087-Super Jumping! Jumping! Jumping!

    Super Jumping! Jumping! Jumping! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K ...

  6. OpenStack组件系列☞Keystone搭建

    一:版本信息 官网:http://docs.openstack.org/newton/install-guide-rdo/keystone.html 二:部署keystone 官网文档:http:// ...

  7. ELMo解读(论文 + PyTorch源码)

    ELMo的概念也是很早就出了,应该是18年初的事情了.但我仍然是后知后觉,居然还是等BERT出来很久之后,才知道有这么个东西.这两天才仔细看了下论文和源码,在这里做一些记录,如果有不详实的地方,欢迎指 ...

  8. win10 uwp 手把手教你使用 asp dotnet core 做 cs 程序

    本文是一个非常简单的博客,让大家知道如何使用 asp dot net core 做后台,使用 UWP 或 WPF 等做前台. 本文因为没有什么业务,也不想做管理系统,所以看到起来是很简单. Visua ...

  9. 51nod1327 棋盘游戏

    远古大坑 神仙DP状态设计题 https://blog.csdn.net/white_elephant/article/details/83592103 从行的角度入手,无论如何都要状压 每列最多放一 ...

  10. Vue v-if和v-show的使用.区别

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...