Deprecated: 函数 get_currentuserinfo 自版本 4.5.0 起已弃用!请使用 wp_get_current_user() 替代。 in /data/home/qxu1142130176/htdocs/wp-includes/functions.php on line 5383
最新消息:

CAS(Compare and Swap)分析理解

数据库 前端收藏 1308浏览

CAS 原理

Compare and Swap,解决多线程并行情况下使用锁造成性能损耗的一种机制,CAS操作包含三个操作数——内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。无论哪种情况,它都会在CAS指令之前返回该位置的值。CAS有效地说明了“我认为位置V应该包含值A;如果包含该值,则将B放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可。
当同时存在读写线程时,默认情况下是不保证线程安全的,因而需要利用信号量来进行线程同步(Synchronization),如关键代码段、互斥体等, 同时操作系统也提供了相应的API。然而同步并不总是满足条件的且有效率的,比如陷入内核时会有性能损失、死锁、活锁以及资源浪费等。

有啥用处?

对于常用多线程编程的人估计知道,对于一般人估计都不曾听说。在jdk5之前,我们知道,在多线程编程的时候,为了保证多个线程对一个对象同时进行访问时,我们需要加同步锁synchronized,保证对象的在使用时的正确性,但是加锁的机制会导致如下几个问题

1.加多线程竞争下,加锁和释放锁会导致较多的上下文切换,引起性能问题。

2.多线程可以导致死锁的问题。

3.多线程持有的锁会导致其他需要此锁的线程挂起。

4……

有更好的办法么?

锁的分类:独占锁(悲观锁),乐观锁

独占锁:synchronized就是一种独占锁,它会导致所有需要此锁的线程挂起,等待锁的释放。

乐观锁:每次不加锁去完成操作,如果因为冲突失败就重试,直到成功。

CAS的机制就相当于这种(非阻塞算法),CAS是由CPU硬件实现,所以执行相当快.CAS有三个操作参数:内存地址,期望值,要修改的新值,当期望值和内存当中的值进行比较不相等的时候,表示内存中的值已经被别线程改动过,这时候失败返回,当相等的时候,将内存中的值改为新的值,并返回成功。

在 java.util.concurrent.atomic包中可以查看源代码的实现,这里参java.util.concurrent.atomic.AtomicLong源代码,贴出核心代码:

    //+1操作
    public final long getAndIncrement() {
        while (true) {
            long current = get();
            long next = current + 1;
            //当+1操作成功的时候直接返回,退出此循环
            if (compareAndSet(current, next))
                return current;
        }
    }
    //调用JNI实现CAS
    public final boolean compareAndSet(long expect, long update) {
        return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
    }

 

转载请注明:前端收藏 » CAS(Compare and Swap)分析理解