Sequential Consistency一致性

  掌握了Sequential Consistency一致性模型之后,我们重新审视一下java的并发。

  我们已经说过,Sequential Consistency只保留进程本地顺序。上文中我们了解到,由于CPU指令重排序、内存多级缓存不一致等问题,硬件层次没有提供Sequential Consistency,需要软件开发人员实现。下面我们就来看一下,在java中如何实现Sequential Consistency。

  Java中Sequential Consistency的基础,是JVM的happens-before关系。在Java Language Specification的内存模型中,规定了happens-before关系,正确处理happens-before关系,是java语言正确实现并发的基础。显而易见的是,在同一个线程的代码中,前面的action happens-before 后面的action。然而它后面又说,两个action就算有happens-before关系,在实现中也不一定按照这个顺序发生。重新排序后的顺序只要能产生合法的结果,就可以接受。

  


  注意,这里说的是“合法”的结果,并不代表这个“合法”的结果符合你的预期。

  更确切的说,两个action如果有happens-before关系,对于和它们没有happens-before关系的代码来说,它们不一定按照这个顺序发生。

  举个例子,对于同时访问数据的两个线程来说,一个线程里的写操作在另一个线程里的读操作看来,有可能是

  


  举个例子来看一下吧。假设两个线程X和Y能共同访问两个变量A和B,A和B初始值为0。

  在X线程中执行

  


  在Y线程中同时读取A和B(实际上java中没法同时原子性的读取两个变量,我们可以先读取B,再读取A),那么有没有可能读取到B=5,A=0呢?直觉上来看,是不可能的。因为X先更新A,后更新B,如果B都读取到了5,那A应该也是5才对。

  


  但是java内存模型明确指出,这种情况是有可能的。因为某个编译器认为

  


  


  也没有什么区别嘛,所以先执行哪个也没关系,所以大刀阔斧的调换了顺序。

  


  所以为了得到需要的结果,在编程时需要建立正确的happens-before关系。建立的方法,可以参考java语言规范。

  比如java语言规范就规定了对volatile字段的写入,happens-before后续对该字段的读取。happens-before关系确定以后,不仅让volatile字段的值让所有线程立即可见,还限制了对该字段访问操作的reorder。


转载于:https://juejin.im/post/5cece434e51d457759648693

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值