在·@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.如果竞争激烈,重试会频繁发生,反而影响效率