CAS笔记

来源:互联网 发布:淘宝店铺在哪里找 编辑:程序博客网 时间:2024/06/05 22:47

  java提供两种实现锁的机制,像Syncronized这种,是通过JVM来实现。

 而像AtocmicInteger,这些concurrent包中的一些类是通过CAS原语来保证。


 CAS基于CPU硬件指令来完成的。

 基本原理:一个旧值(每次更新操作语句前,从内存中取出的值),一个新值(操作的结果值),一个期望值(在调用cpu的CompareAndSet时的方法,会从内存中取出最新值)

这时比较旧值和期望值是否相同,相同就将新值写入到内存。

 java通过调用JNI(C实现),来提供CAS操作的几个封装类,语句如下:

 

unsafe.compareAndSwapInt(this, valueOffset, expect, update);

类似:

if (this == expect) {

  this = update

 return true;

} else {

return false;

}


这里的this,指CPU一二级缓存,对应的变量存储地址

这里有个问题,如果保证this==expect和this=update语句的原子性?

单CPU时,不需要考虑这个问题。但存在多CPU怎么办?

注:CPU能够保证单字节的原子性。有些处理器能够保证8/16/32/64操作的原子性。

cpu提供两种机制来保证 :

1.锁住总线,即CPU1执行compareAndSet时,发出一个LOCK命令,锁住整个总线,这时其它CPU无法再进行内存操作,开销较大。

2.利用缓存锁定,只锁定内存变量对应的CPU一二级缓存地址。即控制,对于同一个内存变量,多个CPU在一二级缓存中对其回写操作,只有第一个生效。

这时之后的n个CPU会触发cache失效,需要从内存中取最新的变量值,这时需要通过总线来取。

过多的CPU cache失效,会导致总线流量过大。


0 0
原创粉丝点击