• Java 线程 — JMM Java内存模型


    JMM

    Java Memory Model,Java内存模型,属于语言级的内存模型

    并发编程中存在的问题:

    • 如何通信:用于线程之间交换信息。两种方式:共享内存,消息传递
    • 如何同步:用于控制不同线程间操作发生的相对顺序。共享内存的同步是显式的,消息传递的同步是隐式的,因为消息发送必须在消息接受之前,已经隐式包含了这个顺序关系

    Java并发采用的是共享内存模型,内存模型的抽象结构如下图:

    线程A和线程B通信的两个步骤:

    1. 线程A把本地内存中更新过的共享变量刷新到主内存中去
    2. 线程B去主内存中读取线程A之前更新过的共享变量
      JMM通过控制主内存和线程的本地内存之间的交互,来为程序提供内存可见性的保证

    重排序

    在执行程序时,为了提高性能,编译器处理器会对指令做重排序,包括以下三类:

    1. 编译器在不改变单线程语意的前提下对语句执行顺序的优化
    2. 处理器对不存在数据依赖性的语句,改变语句对应指令的执行顺序
    3. 内存系统的重排序

    也就是说从Java源码到实际执行的指令序列经历了:
    源代码——>编译器优化——>处理器优化——>内存系统重排序——>实际执行的指令序列
    上述重排序都可能导致内存可见性问题
    JMM属于语言级内存模型,在不同的编译器(软件)和不同的处理器平台(硬件)之上,通过以下方法保证一致的内存可见性:

    1. JMM的重排序规则禁止特定编译器的编译成排序
    2. JMM的处理器重排序规则会要求编译器在生成指令序列时,插入特定的内存屏障(Memory Barriers)指令

    以上JMM的各种禁止重排序的规则和实现确保了happens-before

    happens-before

    基本原则

    在保证执行结果正确的前提下尽可能提高执行的并行度

    定义

    • 如果A操作happens-before B,那么操作A的结果一定对操作B可见,而且操作A的执行顺序一定排在操作B前面(面向程序员:向程序员保证内存可见性)
    • 两个操作存在happens-before关系,并不意味着Java平台的具体实现必须按照happens-before关系指定的顺序执行,只要保证执行结果正确JMM允许重排序(面向编译器和处理器:保证结果正确的前提下尽可能的优化并发性能)

    规则

    1. 程序顺序规则:一个线程中每一个操作,happens-before于该线程所有后续操作
    2. 监视器锁规则:对于一个锁的解锁,happnes-before于对同一个锁的加锁
    3. volatile规则:对于volatile域的写,happens-before于任意后续对这个域的读
    4. 传递性规则:如果A happens-before于B,B happens-before于C,那么A happens-before于C
    5. start()规则:如果线程A执行ThreadB.start()操作,那么线程ThreadB.start()操作happens-before于ThreadB的任何操作
    6. join()规则:如果线程A执行ThreadB.join()操作并成功返回,那么ThreadB的任何操作happens-before于线程A从ThreadB.join()成功返回

    写缓冲区

    现代处理器使用写缓冲区临时保存向主存写入的数据,可以避免由于处理器向主存中写入数据而产生的延迟(对内存的读写速度远慢于处理器运行速度,对寄存器或者缓存的读写速度快于对)

    数据依赖

    JMM的重排序规则只会保证单线程的数据依赖正确
    JMM只保证正确同步的并发操作是正确的(和顺序一致内存模型得到的结果相同)

    顺序一致性内存模型

    • 理想模型
    • 一个线程中所有操作必须 按照程序顺序执行
    • 每个操作原子执行,并且对所有线程立即可见(实际情况:没有原子执行,因为缓存也不能立即可见),因为立即可见,所以整体上所有线程看到的都是一个单一的执行顺序
  • 相关阅读:
    js调用oc方法 UIWebView 跳 到另一个UIWebView
    可变cell,自适应cell,理解iOS 8中的Self Sizing Cells和Dynamic Type
    设置textField的placeholder字体的颜色,默认是灰色
    设置按钮(UIButton)为圆角矩形
    UITextView限制输入字数
    如何更好地限制一个UITextField的输入长度
    uitableview style类型为Grouped时,去掉上面空白的方法
    python note 01 计算机基础与变量
    Leetcode61.旋转链表
    Leetcode 430. 扁平化多级双向链表
  • 原文地址:https://www.cnblogs.com/sunshine-2015/p/6028129.html
Copyright © 2020-2023  润新知