CAS无锁算法

锁(lock)的代价

锁是用来做并发最简单的方式,当然其代价也是最高的。内核态的锁的时候需要操作系统进行一次上下文切 换,加锁、释放锁会导致比较多的上下文切换和调度延时,等待锁的线程会被挂起直至锁释放。在上下文切换 的时候,cpu之前缓存的指令和数据都将失效,对性能有很大的损失。用户态的锁虽然避免了这些问题,但是 其实它们只是在没有真实的竞争时才有效。

Java在JDK1.5之前都是靠synchronized关键字保证同步的,这种通过使用一致的锁定协议来协调对共享状态的访问,可以确保无论哪个线程持有守护变量的锁,都采用独占的方式来访问这些变量,如果出现多个线程同时 访问锁,那未抢到锁的线程将被挂起,当线程恢复执行时,必须等待其它线程执行完他们的时间片以后才能被 调度执行,在挂起和恢复执行过程中存在着很大的开销。锁还存在着其它一些缺点,当一个线程正在等待锁 时,它不能做任何事。如果一个线程在持有锁的情况下被延迟执行,那么所有需要这个锁的线程都无法执行下 去。如果被阻塞的线程优先级高,而持有锁的线程优先级低,将会导致优先级反转(Priority Inversion)。

乐观锁与悲观锁

独占锁是一种悲观锁,synchronized就是一种独占锁,它假设最坏的情况,并且只有在确保其它线程不会造成干扰的情况下执行,会导致其它所有需要锁的线程挂起,等待持有锁的线程释放锁。而另一个更加有效的锁就 是乐观锁。 所谓乐观锁就是,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直 到成功为止

CAS无锁算法

要实现无锁(lock-free)的非阻塞算法有多种实现方法,其中 CAS(比较与交换,Compare and swap) 是 一种有名的无锁算法。CAS, CPU指令,在大多数处理器架构中都支持调用。 CAS的语义是“我认为V的值应该 为A,如果是,那么将V的值更新为B,否则不修改并告诉V的值实际为多少” 。
CAS是项乐观锁技术,当多个线程尝试使用CAS同时更新同一个变量时,只有其中一个线程能更新变量的值, 而其它线程都失败,失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次尝试。 CAS有3个操作 数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否 则什么都不做

举个例子:
一 如图所示,现在有一个int 的值id = 1,现在有A和B两个线程都要对这个id进行输入操作。
在CAS中的三个操作数就如图中所示:
在这里插入图片描述
二 现在A线程首先对id值进行操作,V值为1,A值为1,V=A,所以将A值得转换成B,所以现在的id的值为2,A线程操作完之后,B线程对id进行操作,发现V值为2,A值为1,V!=A,所以B值不改变,将A值变成2,线程B重新进行尝试,再测尝试发现V=A,所以将B的值改成3。如果再次尝试V还是不等于A的值,就继续进行尝试,直到B值进行改变。
在这里插入图片描述

自我对CAS的理解,如有不对之处请指正

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值