美文网首页
Java内存模型

Java内存模型

作者: 34sir | 来源:发表于2018-02-22 10:24 被阅读10次

    如果对内存模型没有一个基本的了解,建议先看有关并发编程

    书归正传,以大家都已经熟悉了内存模型中的原子性可见性有序性为前提,我们来聊一聊Java对这三者提供了哪些保证

    原子性

    分析一下下面的这段代码,看看哪些是原子性操作

    x = 1;         //语句1
    y = x;         //语句2
    x++;           //语句3
    x = x + 1;     //语句4
    

    答案:只有语句1才是原子性操作

    下面我们分析一下:
    语句1:单纯的将数值1赋给x,也就是直接将1写入到工作内存中,一个步骤,显然满足原子性
    语句2:先读取x的值,再将x的值写入工作内存,两个步骤,显然不满足原子性
    语句3:先读取x的值,然后进行加一操作,然后写入工作内存,三个步骤,显然不满足原子性
    语句4:同语句三,有三个步骤,不满足原子性

    对于原子性的判断做个总结:
    只有简单的读取、赋值(而且必须是将数值赋值给某个变量,变量之间的相互赋值不是原子操作)才是原子操作
    如果要实现更大范围操作的原子性,可以通过synchronized和Lock来实现

    可见性

    Java保证可见性的,两种方式:

    • volatile
      当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去主存中读取新值
    • synchronized和Lock
      synchronized和Lock能保证同一时刻只有一个线程获取锁然后执行同步代码,并且在释放锁之前会将对变量的修改刷新到主存当中,所以,可以保证可见性

    有序性

    Java保证有序性的两种方式

    • volatile
      可以保证一定的有序性,具体的原理我会的单独分一篇来分析volatile
    • synchronized和Lock
      保证每个时刻是有一个线程执行同步代码,相当于是让线程顺序执行同步代码,这样显然就具备有序性

    关于有序性,Java中默写情况下是默认具备有序性的,这个通常被叫做happens-before原则,满足此原则的就能保证有序性

    下面介绍一下happens-before(先行发生)原则:

    • 次序规则:同一个线程中,按照代码的顺序,书写在前面的操作优先发生于书写在后面的操作
      这个描述其实不太准确,因为有指令重排,这个规则的意思其实是:即使发生了指令重排,我们也可以当做按照代码顺序执行来理解,因为结果是相同的
    • 锁定规则:一个unLock操作先行发生于后面对同一个锁的lock操作
      锁定状态,解锁在加锁之前
    • volatile规则:对一个变量的写操作先行发生于后面对这个变量的读操作
    • 传递原则:A先发生于B,并且B先发生于C,那么A先发生于C

    相关文章

      网友评论

          本文标题:Java内存模型

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