JVM层级的内存屏障:JSR内存屏障

JSR内存屏障:
  1. LoadLoad:对于这样的语句Load1;LoadLoad;Load2,在Load2及后续的读操作要读取的数据被访问前,保证Load1要读取的数据被读取完毕;
  2. StoreStore:对于这样的语句Store1;StoreStore;Store2,在Store2及后续的写操作执行前,保证Store1的写入操作对其他处理器可见;
  3. LoadStore:对于这样的语句Load1;LoadStore;Store2,在Store2及后续的写入操作被刷出前,保证Load1要读取的数据被读取完毕;
  4. StoreLoad:对于这样的语句Store1;StoreLoad;Load2,在Load2及后续的读操作要读取的数据被访问前,保证Store1的写入操作对其他处理器可见;

  as-if-serial:不管如何重排序,单线程执行结果不会改变。在JVM层面volatile的实现细节特别保守,保证了内存可见性,并且成功防止指令重排序。如果是对对象加入volatile,是对该对象前后加入内存屏障,具体的实现细节如下所示:

StoreStoreBarrier
volatile 写操作
StoreLoadBarrier

LoadLoadBarrier
volatile 读操作
LoadStoreBarrier
happens-before原则:

  happens-before原则是Java内存模型中定义的两个操作之间的偏序关系。比如说操作A先行发生于操作B,那么在B操作发生之前,A操作产生的“影响”都会被操作B感知到。这里的影响是指修改了内存中的共享变量、发送了消息、调用了方法等。

  1. 程序顺序规则: 一个线程中的每个操作,happens-before于该线程中的任意后续操作;
  2. 监视器锁规则: 对每一个锁的解锁,happens-before于随后对该锁的加锁;
  3. Volatile变量规则:对一个volatile域的写,happens-before于任意后续对这个volatile域的读;
  4. 线程启动规则:Thread的start()方法先行发生于这个线程的每一个操作;
  5. 线程终止原则:线程的所有操作都先行于此线程的终止检测,可以通过Thread.join()方法结束、Thread.isAlive()的返回值等手段检测线程的终止;
  6. 线程中断原则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生,可以通过Thread.interrupt方法检测线程是否中断;
  7. 对象终结规则:一个对象的初始化完成先于发生它的finalize()方法的开始;
  8. 传递性: 如果A happens-before B, B happens-before C, 那么A happens-before C;
volatile关键字修饰变量的特殊规则:
  1. 可见性:对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入。
  2. 原子性:对任意单个volatile变量的读/写具有原子性,但类似于volatile++这种复合操作不具有原子性。
final域的重排序规则:
  1. 在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序;
  2. 初次读一个包含final域的对象的引用,与随后初次读这个final域,这两个操作之间不能重排序;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值