美文网首页
Java内存模型:如何解决有序性和可见性问题

Java内存模型:如何解决有序性和可见性问题

作者: 潇湘哥哥 | 来源:发表于2020-11-08 00:29 被阅读0次

    继上一篇:多线程安全问题:可见性、原子性、有序性

    引言


    1. Happens-Before 的语义本质上是一种可见性
      A Happens-Before B 意味着 A 事件对 B 事件来说是可见的,无论 A 事件和 B 事件是否发生在同一个线程里。
    2. 三个关键字:synchronized、volatile、final

    什么是Java内存模型

    Java内存模型规范了JVM如何按需禁用内存和编译优化
    具体包括:三个关键字(synchronized、volatile、final)及Happens-Before原则

    Volatile关键字

    1. 原始语义,如 volatile int x = 0,表达的是:告诉编译器,对这个变量的读写,不能使用 CPU 缓存,必须从内存中读取或者写入。

    final关键字

    1. final 修饰变量时,初衷是告诉编译器:这个变量生而不变,可以可劲儿优化。
    2. 避免构造函数 ”逸出“
    final int x;
    public FinalFieldExample() {
          x = 3;
          y = 4;
          global.obj = this; // this逸出;线程通过 global.obj 读取 x 有可能读到 0 
    }
    

    Happens-Before原则

    1. 前面一个操作的结果对后续操作是可见的
    2. 具体规则:
    • 程序的顺序性规则:程序前面对某个变量的修改一定是对后续操作可见的
    • Volatile变量规则:对一个 volatile 变量的写操作, Happens-Before 于后续对这个 volatile 变量的读操作
    • 传递性规则:如果 A Happens-Before B,且 B Happens-Before C,那么 A Happens-Before C
    • 管程锁规则:对一个锁的解锁 Happens-Before 于后续对这个锁的加锁。
    • 线程start()规则:如果线程 A 调用线程 B 的 start() 方法,那么该start() 操作 Happens-Before 于线程 B 中的任意操作。
    • 线程join()规则:如果在线程 A 中,调用线程 B 的 join() 并成功返回,那么线程 B 中的任意操作 Happens-Before 于该 join() 操作的返回
    • 线程interrupt()规则:对线程interrupt() 方法的调用先行发生于被中断线程的代码检测到中断事件的发生
    • 对象finalize规则:一个对象的初始化完成先行发生于他的finalize() 方法的开始

    重点:Volatile变量规则

    相关文章

      网友评论

          本文标题:Java内存模型:如何解决有序性和可见性问题

          本文链接:https://www.haomeiwen.com/subject/opscbktx.html