zoukankan      html  css  js  c++  java
  • 02-java内存模型:解决并发编程的可见性、有序性问题

    并发编程的两个问题:缓存导致的不可见,编译优化导致的有序性问题

    解决:禁用缓存,禁用编译优化。但是总不能所有程序都禁用吧,这样程序的性能就堪忧了。

    Java内存模型:按需禁用缓存,禁用编译优化。

    从本质上来讲,Java内存模型规范了JVM如何提供按需禁用缓存和编译优化的方法。具体来说,这些方法包括volatile、synchronized、和final三个关键字,以及七项happens-before规则。

    一、volatile

      它修饰的变量,告诉编译器,对这个变量的读写,不能使用cpu缓存,必须从内存中读取或写入。

    二、synchronized

      管程,在Java中指的就是synchronized。在进入代码块之前,会自动加锁,在代码块执行完会自动释放锁。

    三、final

      它修饰的变量,告诉编译器:这个变量生而不变,可以可劲儿优化。

    happens-before规则:

    1、程序的顺序性规则

    指在一个线程中,按照程序顺序,前面的操作happens-before于后续的任意操作

    2、volatile变量规则

    指 对一个volatile变量的写操作,happens-before于后续对这个volatile变量的读操作。

    3、传递性

    如果A  happens-before于B,B happens-before于 C,那么A happens-before 于 C。

    4、管程中锁的规则

    即synchronized代码块happens-before于后续进入该代码块以及后续的所有操作。

    5、线程start()规则

    线程A启动子线程B,那么子线程B能够看到线程A在启动线程B前的操作。

    6、线程join()规则

    这条是关于线程等待的。在线程A中调用线程B的join()并成功返回,那么线程B中的任意操作happens-before于该join()操作的返回。

    7、线程终止规则

    (1).线程终止规则:线程中的所有操作都先行发生于对此线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值等手段检测到线程已经终止执行。
    (2).线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生,可以通过Thread.interrupted()方法检测到是否有中断发生。

    四、Java内存模型底层怎么实现的?

    主要是通过内存屏障(memory barrier)禁止重排序的,即时编译器根据具体的底层体系架构,将这些内存屏障替换成具体的 CPU 指令。对于编译器而言,内存屏障将限制它所能做的重排序优化。而对于处理器而言,内存屏障将会导致缓存的刷新操作。比如,对于volatile,编译器将在volatile字段的读写操作前后各插入一些内存屏障。

  • 相关阅读:
    利用beautifulsoup4解析Kindle笔记
    对流媒体传输关键指标作简单预测
    Linux上使用Windows软件
    Tex家族关系
    数学基础-概率论05(统计推断-分布拟合检验)
    数学基础-概率论04(统计推断-参数假设检验)
    数学基础-概率论03(统计推断-参数估计)
    数学基础-概率论01(离散型分布)
    数学基础-概率论02 (连续型分布)
    Calibre中使用DeDRM插件进行Kindle电子书解锁
  • 原文地址:https://www.cnblogs.com/bbsh/p/11657669.html
Copyright © 2011-2022 走看看