美文网首页
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