【多线程】cas

在·@TOC

一、定义
  • 1.compareAndSet,简称CAS
  • 2.也有Compare And Swap的说法
  • 3.必须是原子操作,在cpu的指令级别实现原子性
  • 4.compareAndSet方法内部是原子的,但不是用锁实现的
二、工作原理举例
  • 1.线程1和线程2对共享变量a=100改值
  • 2.线程1获取a的值为100,准备改为80
  • 3.线程2获取共享变量a的值,并做了修改,改为了90
  • 4.线程1compareAndSet(100,80),将100与变量的当前值90进行比较,此时100与90不相同,便返回false,此次修改失败
  • 5.循环后,线程1获取a的值为90,准备改为80,线程1compareAnsSet(90,80),将90与变量的当前值90进行比较,此时90与90相同,便将共享变量a的值改为80,并返回true,当返回true,跳出循环
三、底层原理
  • 1.cas的底层是lock cmpxchg指令(x86架构),在单核cpu和多核cpu下都能够保证比较-交换的原子性
  • 2.在多核状态下,某个核执行到带lock的指令时,cpu会让总线锁住,当这个核把此指令执行完毕,再开启总线。这个过程中不会被线程的调度机制所打断,保证了多个线程对内存操作的准确性,是原子的
四、cas与volatitle
  • 1.获取共享变量时,为了保证该变量的可见性,需要使用volatile修饰
  • 2.volatile用来修饰成员变量和静态成员变量,可以避免线程从自己的工作缓存中查找变量的值,必须到主存中获取它的值,线程操作volatile变量都是直接操作主存,即一个线程对volatitle变量的修改,对另一个线程可见
  • 3.volatile仅仅保证了共享变量的可见性,让其它线程能够看到最新值,但不能解决指令交错问题(不能保证原子性)
  • 4.cas必须借助volatile才能读取到共享变量的最新值来实现“比较并交换”的效果
五、cas为什么比synchronized效率高
  • 1.无锁情况下,即使cas重试失败,线程始终在高速运行;synchronized会让线程在没有获得锁时,会发生上下文切换,线程进入阻塞,发生上下文切换的代价是比较大的,线程信息需要被保存,被保存的线程信息再被恢复
  • 2.无锁情况下线程要保持运行得需要另一个cpu的支持,当线程执行时虽然不会阻塞,但没有分到时间片,依然会进入可运行状态,导致上下文切换
  • 3.cas在多核cpu的情况下才能发挥优势,且线程数不能超过cpu的核心数,超过了则没有额外的cpu执行而导致上下文切换
六、cas的特点
  • 1.结合cas和volatile可以实现无锁并发,适用于线程少,多核cpu的场景下
  • 2.cas是基于乐观锁的思想:最乐观的估计,不担心别的线程来修改共享变量,即使改了也不影响,可以继续重试
  • 3.synchronized是基于悲观锁的思想:最悲观的估计,得防着其它线程来修改共享变量,当持有锁,其它线程都不能改,等解开锁,其它线程才有机会
  • 4.cas体现的是无锁并发、无阻塞并发
  • 5.因为没有使用synchronized,所以线程不会陷入阻塞,是效率提升的因素之一
  • 6.如果竞争激烈,重试会频繁发生,反而影响效率
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王佑辉

老板,赏点吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值