volidate与可见性

volidate是java中用来保证并发访问同一状态的可见性的一种工具。可见性是指一个线程对内存中某一地址的值修改必定能对其他访问该地址的线程生效。听起来是个理所当然的事,但这简单的事背后却有一套复杂的机制来保证。其复杂机制产生的原因是在cpu和内存间加入缓存所导致的,缓存协调了CPU和内存间效率不一致的问题,但引入了内存不可见的问题。cpu访问内存时,一次性将内存中的一页读到缓存中,再从缓存中读取指定地址的值用于操作,如果当某一个cpu修改了某地址的状态的同时又有另一个cpu同时也对该地址进行读或者写,可想而知在两个缓存中同一地址的值很可能是不同的,那么哪个缓存中的值应该被写回内存中呢?凡事讲个先来后到,所以cpu先写回的缓存应该写回内存,而另一个缓存的值将变为无效。这种机制通过mesi协议来保证,mesi代表了缓存的四种状态,每个缓存监听其他缓存的状态变化,据此改变自身的状态。E代表该地址被cpu独占,没有其他cpu的缓存有该地址;而当另一个cpu也要访问该地址时,之前的cpu该地址缓存状态变为s,同时新来的cpu的该缓存地址状态也是s,所以s表示该地址共享;如果两个cpu中的一个对该地址进行写操作,那么这一个cpu的该地址状态就变为m,而另一个cpu的缓存中该地址将变为i,所以m就代表修改,i代表无效。被修改的地址的值应该被写回内存中,但这个效率和cpu的运行效率相比非常慢,如果cpu等待地址对应的值写回内存,什么事都不干就太浪费了,所以就先不写回内存。但修改的值肯定一定必须写回内存,那么就引入了storeBuffers和无效队列这两个组件。cpu对地址的值写不再直接写入缓存而是storebuffers中,cpu可立即往下执行。storebuffers在某一时刻向无效队列写入消息,立即获得响应,而无效队列按队列顺序设置缓存中的地址状态为无效。那么问题就来了,因为改变的状态没有同步更新,其他cpu可能在别的cpu改写地址的值时去读取地址的值,这就产生了状态不一致的问题。硬件上无法确定哪个操作应该优先,所以提供memorry barrier给软件来控制操作的先后。java中volidate就是用来表示memorry barrier,当对volidate修饰的变量赋值时那么编译器会添加一个write memorry barrier,其作用是将缓存中的状态写回内存;当对volidate修饰的变量赋值时那么编译器会添加一个read memory barrier,其作用是强制读内存中状态

转载于:https://my.oschina.net/u/4003871/blog/3074501

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值