您的位置:首页 > 编程语言 > Java开发

Java CAS理解

2015-07-31 17:33 405 查看
CAS(Compare and Swap),总结起来就只有一句话:CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。

首先说明一下最有名的synchronized的同步锁机制。

synchronized是一种独占锁,独占锁是一种悲观锁。所谓的悲观锁的悲观的意思就是“对于临界区的资源,悲观的认为其他的线程一定会被其他的线程所修改”。

CAS是乐观锁,乐观的意思表示“先假设临界区的资源只会由我一个人修改,如果出错,我再修改”。

好几处博客举的例子都是AtomicInteger类的如下代码段,但是都没有怎么说清楚。现在我想用我的理解详细的解释一下过程。

[code]public final int incrementAndGet() {
    for (;;) {
        int current = get();
        int next = current + 1;
        if (compareAndSet(current, next))
            return next;
    }
}


首先假设有一个变量i,i的初始值为0。每个线程都对i进行+1操作。CAS是这样保证同步的。

假设有两个线程,线程1读取内存中的值为0,current = 0,next = 1,然后挂起,然后线程2对i进行操作,将i的值变成了1。线程2执行完,回到线程1,进入if里的compareAndSet方法,该方法进行的操作的逻辑是,(1)如果操作数的值在内存中没有被修改,返回true,然后compareAndSet方法返回next的值(2)如果操作数的值在内存中被修改了,则返回false,重新进入下一次循环,重新得到current的值为1,next的值为2,然后再比较,由于这次没有被修改,所以直接返回2。

CAS算法实现一个重要前提需要取出内存中某时刻的数据,而在下时刻比较并替换,那么在这个时间差类会导致数据的变化。

比如说一个线程one从内存位置V中取出A,这时候另一个线程two也从内存中取出A,并且two进行了一些操作变成了B,然后two又将V位置的数据变成A,这时候线程one进行CAS操作发现内存中仍然是A,然后one操作成功。尽管线程one的CAS操作成功,但是不代表这个过程就是没有问题的。如果链表的头在变化了两次后恢复了原值,但是不代表链表就没有变化。

以上就是我对CAS原理实现的理解,欢迎指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: