20050824V1CAS(Compare And Swap)分析。

20050824V1CAS(Compare And Swap)分析。

重新迷茫

CAS(Compare and Swap)是一律种实现起原子操作的机制!

情怀感觉更不好了,经常容易模糊。浑浑噩噩的过了一个月,自己还没有真的的潜进去。很多事物还开得死虚,很透。虽然有上看B很辛苦,但是它立马要运动了,我真正好舍不得她走。她走了,我也为不懂得自己到底要举行些什么。

从根本上说,CAS是经过硬件方式贯彻。JVM只是包裹了汇编调用,那些AtomicInteger类便是以了这些包裹后的接口。

A

简易介绍一下此令的操作过程:首先,CPU会以内存中将要被重复改之多少及巴的值做比。当这简单个价相当时,CPU才见面以内存中的数值替换为新的价值,否则就是不举行操作。最后,CPU
会将眼前变量的实价值返回。这同一多元之操作是原子的。

管之布局即是三单:

CAS是一律种植乐观锁的思绪,它相信在它修改前,没有其他线程去窜其。而synchronized是一模一样栽悲观锁,它当于她修改前,一定会起任何线程去修改它,悲观锁效率很没有。

P

虽CAS的频率非常高,但是CAS会引发ABA问题:
(1)进程P1在共享变量中读到值为A
(2)P1被吞没了,进程P2执行
(3)P2把共享变量里的值从A改成为了B,再转回到A,此时让P1抢占。
(4)P1回来探望共享变量里之价没有让转,于是继续执行。
尽管如此P1以为变量值没有转,继续执行了,但是这个会引发部分地下的题目。ABA问题在地点重用方面影响很可怜,而地方被引用是不行经常有的,一个内存分配后放了,再分配,很有或还是本来的地址,但是地方所对的内存内容既变了。

:PAR

CAS,Compare
And Swap,即于并交换。Doug
lea在共组件中大量使CAS技术鬼斧神工地落实了Java多线程的起操作。整个AQS同步组件、Atomic原子类操作等等都是坐CAS实现之,甚至ConcurrentHashMap在1.8底版被吗调动为CAS+Synchronized。可以说CAS是全体JUC的基本。
CAS分析
每当CAS中生三单参数:内存值V、旧的意料值A、要更新的值B,当且仅当内存值V的值等于旧的料想值A时才见面以内存值V的值修改也B,否则什么都非关乎。其伪代码如下:

V

if(this.value == A){
    this.value = B
    return true;
} else{
    return false;
}

:V3R

JUC下的atomic类都是经CAS来贯彻之,下面就以AtomicInteger为条例来阐释CAS的贯彻。如下:

B

private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
static 
{
    try 
       {
            valueOffset = unsafe.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (Exception ex)
        { 
            throw new Error(ex); 
        }
 }
private volatile int value;

:EM

注:
(1)valueOffset为变量值在内存中的摆地址,unsafe就是通过摇地址来抱数码的原值的。
(2)value当前值,使用volatile修饰,保证多线程环境下看见的是同一个。volatile保证可见性,但是非保证原子性

于是我觉着温馨真正是发生点儿局外人的意思。P方面,自己开了一致次于PA报告,也非知晓会不见面成为寻常的一个于主要之喻。V这边,参与了简单单告知,A和NB,兴趣不大,技术含量不强。估计在抢之前程会晤抖动下。那么后来自我还会连下去什么吗?我有少数迷茫。

俺们便以AtomicInteger的compareAndSet方法来举行证,先看源代码:

B这边我几乎从未外业务做,SJ做用分析,D做MTP,我要好挂的衔是读书各种的G,但实在根本就因故不达,我开始有些动摇,怀疑自己当初当有用、非常实惠之物是否确实一无是处。不管则么说,该套的应学下,下面自己的突破口应置身何?P太复杂,自己差日外也难切入,最有益的饶是各种AR了,自己不光要学会如何错过开这些告诉,还要上怎么错过下他们,这虽是自若尽力的方向咯。

/**
 * Atomically sets the value to the given updated value
 * if the current value {@code ==} the expected value.
 *
 * @param expect the expected value
 * @param update the new value
 * @return {@code true} if successful. False return indicates that
 * the actual value was not equal to the expected value.
 */
public final boolean compareAndSet(int expect, int update) {
    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}

里头调用unsafe的compareAndSwapInt方法:
public
native boolean compareAndSwapInt(Object obj, long offset,int expect, int
update); 
以obj的offset位置较integer
field和期望的值,如果同则更新。这个法子的操作应该是原子的,因此提供了同栽不可中断的艺术创新integer
field。
拖欠方法吗本地方法,有四单参数,分别表示:对象、对象的地址、预期值、修改值。

CAS可以保平等不行的读-改-写操作是原子操作,在就处理器上该操作轻实现,但是在多处理器上落实就起少复杂了。CPU提供了有限种植艺术来落实多处理器的原子操作:总线加锁或者缓存加锁。
总线加锁:总线加锁就是就是是下电脑提供的一个LOCK#信号,当一个处理器在总线上输出此信号时,其他电脑的请求将让打断住,那么该处理器可以占使用共享内存。但是这种处理方式显得有个别霸道,不厚道,他拿CPU和内存之间的通信锁住了,在锁定期间,其他电脑都无克其他内存地址的多寡,其开来三三两两大。所以即便发生了缓存加锁。
缓存加锁:其实对于地方那种状态我们特需要保证在平等时刻对有内存地址的操作是原子性的即可。缓存加锁就是苏存在内存区域之数据要以加锁期间,当它执行锁操作写回内存时,处理器不在输出LOCK#信号,而是修改中的内存地址,利用缓存一致性协议来管原子性。缓存一致性机制可以确保与一个内存betway必威区域之数才能够给一个计算机修改,也就是说当CPU1窜缓存行中的i时以缓存锁定,那么CPU2便无克而缓存了i的休养生息存行。

CAS缺陷
CAS虽然很快地缓解了原子操作,但是要存在一些短的,主要呈现在三单艺术:循环时最好长、只能保证一个共享变量原子操作、ABA问题。
巡回时太长
倘CAS一直无成功与否?这种状态绝有或发,如果自旋CAS长日子地无成事,则会于CPU带来格外酷的出。在JUC中稍加地方便限制了CAS自旋的次数,例如BlockingQueue的SynchronousQueue。

只好管一个共享变量原子操作
扣押了CAS的兑现即知就只能针对一个共享变量,如果是大抵单共享变量就只好使用锁了,当然要您出法子把多独变量整成一个变量,利用CAS也不易。例如读写锁被state的大地位

ABA问题
CAS需要检讨操作值有无出起反,如果没发生改变则更新。但是在这么平等栽状况:如果一个值原来是A,变成了B,然后以改为了A,那么当CAS检查的时光会意识没有转,但是精神上其早已有了转,这就是是所谓的ABA问题。对于ABA问题该解决方案是添加版本号,即当每个变量都长一个版号,每次转时加1,即A
—> B —> A,变成1A —> 2B —> 3A。

参考:

http://swiftlet.net/archives/2399

admin

网站地图xml地图