最近作新项目,货币充值消耗,送礼竞争勋章等都使用了CAS解决并发问题,因此作一下笔记,谈谈CAS,你们一块儿互相学习。算法
讨论CAS的话,先来讲有一下乐观锁,悲观锁。数据库
悲观锁:每次去取数据,很悲观,都以为会被别人修改,因此在拿数据的时候都会上锁。简言之,共享资源每次都只给一个线程使用,其余线程阻塞,等第一个线程用完后再把资源转让给其余线程。synchronized和ReentranLock等都是悲观锁思想的体现。并发
乐观锁:每次去取数据,都很乐观,以为不会被被人修改。所以每次都不上锁,可是在更新的时候,就会看别人有没有在这期间去更新这个数据,若是有更新就从新获取,再进行判断,一直循环,直到拿到没有被修改过的数据。CAS(Compare and Swap 比较并交换)就是乐观锁的一种实现方式。工具
1.须要读写的内存地址V学习
2.进行比较的预期原值A线程
3.拟写入的新值Bcdn
若是内存位置的值V与预期原A值相匹配,那么处理器会自动将该位置值更新为新值B。CAS思想:要进行更新时,认为位置V上的值仍是跟A值相等,若是是是相等,就认为它没有被别的线程更改过,便可更新为B值。不然,认为它已经被别的线程修改过,不更新为B的值,返回当前位置V最新的值。blog
反编译Unsafe类(用Java Decompiler工具) 内存
假设多人A,B,C等给D送礼,送总价值最多的那我的,能够成为佩带D的守护皇冠,D的守护皇冠有且只有一个。若是他们同时在给D送礼,送礼价值互相超越,即存在并发问题。资源
解决思路: 参考乐观锁原理
抢占守护流程图:
代码实现:
并发环境下,假设初始条件是A,去修改数据时,发现是A就会执行修改。可是看到的虽然是A,中间可能发生了A变B,B又变回A的状况。此时A已经非彼A,数据即便成功修改,也可能有问题。
自旋CAS,若是一直循环执行,一直不成功,会给CPU带来很是大的执行开销。因此上面抢占守护的例子,设置了尝试的执行次数n,避免一直循环