java并发 之 CAS详解

来源:互联网 发布:什么是矩阵图片 编辑:程序博客网 时间:2024/05/18 00:49

CAS 介绍

说到CAS如果大家对java.util.concurrent包下面的类用的不多的话可能就不太了解,但是对CAS这个名称大家应该都听说过吧。NoSQL数据库大家想必也用到过,比如memcached,提到memchched大家一般都不会陌生了,比如memcached提供的原子操作 比如程序计数器,里面就有CAS操作。

memcached 中的CAS指令

现在给大家稍微讲解一下memcached中的原子操作也就是依赖CAS操作的操作步骤,以便与大家理解:

memcahced主要是有gets和cas这两个指令来避免数据的不一致性的,

当我们用gets指令的时候获得到几个值,其中不只有存储的实际值,而且也会得到一个casid,其中我自己的理解 相当于当前值的版本号,用过Elasticsearch 的同学都应该知道,每个文档都有一个版本号码,用于对比操作。这里我也习惯性的叫这个值为版本号。每次有更新操作的时候都会改变的,好的 ,下面咱们开始咱们的流程。

其中Gets是获取数据,而CAS是保存数据的指令,
假如现在有两个线程A、B

A线程现在调用Gets方法,
假如说得到的值是
value:”helllo world”
cas_id : “188”
这个时候A线程还没有进行Set操作。

B线程现在也执行了Gets方法,的到了和A线程获取Gets方法一样的数据,包括value和casid,
这个时候B线程进行了update操作,并把新的value和casid 一起通过CAS命令发送给了memcached ,这个时候当前的casid一定会发生变化,而memcached 对比了B线程传送过来的casid 和 旧的casid进行对比,发现两个casid是一样的,那么进行更新,现在的casid在memcached 中的值变成了189。

这时A线程进行更新操作,然后A线程把自己的值和casid一起发送给memcached, 这个时候memcached发现A线程传送过来的casid是188,而自己的casid是189,结果casid不一样,那么就不会更新,而A线程的到的结果也是更细失败的。

大致思路就是:如果某个键对应的casid和传递给cas命令的casid一致的话那么就进行更新,如果不一致就是更新失败。

这个时候大家是不是稍微有点思路了。其实memcached就是通过CAS来保证数据的一致性的。

java 中的CAS

在java中 java.util.concurrent包下面的并发类几乎全部都是依赖CAS的。

思路其实跟上面提到的是一样的。
CAS其实有三个可操作的值:
第一个是期望值,第二个是内存值,第三个是更新值,
当且仅当预期值和内存值相同时,将内存值修改为更新值,否则什么都不做。是不是感觉和上面提到的原理差不多呢。

而AtomicInteger 就是借助java 中JNI调用C,然后C来调用CPU底层的CAS指令实现。

其中在另外一个博客中写的很好,在这里引用一下:

博客地址:http://blog.csdn.net/hsuxu/article/details/9467651,总结的非常好。我就不献丑了,希望可以帮到大家一起学习java 并发实践。

1 0
原创粉丝点击