“Happens-before”规则和 8种内存交互的原子操作

“Happens-before”规则:

用于保证有序性,假如两个操作之间不存在以下关系,并且无法从以下规则推导出,那么虚拟机可以对去进行随意的重排序:

  • 程序次序规则:在一个线程内,按照程序代码的顺序,书写在前面的操作现行发生于书写在后面的操作。准确的说,应该是控制流的顺序而不是程序代码顺序,因为要考虑分支循环的等结构。
  • 管程锁定规则: 一个unlock操作现行发生于后面一个对同一个锁的lock操作。这里必须强调的是同一个锁,而”后面”是指时间上的先后顺序
  • volatile变量规则:对一个volatitle变量的写操作先发生于后面的对这个变量的读操作,这里的”后面”是指时间上的。
  • 线程启动规则:Thread对象的start()方法先发生于此现成的每一个动作。
  • 线程终止规则: 线程中的所有操作都先发生于对此线程的终止检测,我们可以通过Thread.join()方法结束、Tread.isAlive()方法的返回值等手段检测到线程已经终止执行。
  • 线程中断规则:对线程interupt()方法的调用先行发生于被中断线程的代码检测到中断时间的发生。可以通过Tread.interupted()方法检测到是否发生了中断。
  • 对象最终规则:一个对象的初始化完成(构造函数执行结束)先行发生于它的finalize()方法的开始。
  • 传递性:如果操作A先行发生于操作B,那么B现行发生于操作C,那就可以的操作A现行发生于操作C的结论。

JAVA内存模型中定义了以下8种操作来完成工作内存与主存的交互,虚拟机保证了每一种操作都是原子操作、不可再分的。(double 和 long 类型变量在部分平台允许例外,主要与其在内存中所占位数有关。)

  • lock:作用于主内存,把变量标识为线程独占状态。
  • unlock:作用于主内存,解除独占状态。
  • read:作用主内存,把一个变量的值从主内存传输到线程的工作内存。
  • load:作用于工作内存,把read操作传过来的变量值放入工作内存的变量副本中。
  • use:作用工作内存,把工作内存当中的一个变量值传给执行引擎。
  • assign:作用工作内存,把一个从执行引擎接收到的值赋值给工作内存的变量。
  • store:作用于工作内存的变量,把工作内存的一个变量的值传送到主内存中。
  • write:作用于主内存的变量,把store操作传来的变量的值放入主内存的变量中。

猜你喜欢

转载自blog.csdn.net/CrazyHSF/article/details/81750228