CAS算法
在学习CAS算法前我们需要了解非阻塞算法。
1.非阻塞算法:一个线程结束或挂起不会导致另外的线程结束或挂起。
2.CAS算法:Compare And Swap(比较及交换)是非阻塞算法的一种实现、乐观锁的一种技术、它能在不使用锁的情况下实现多线程安全,CAS也是一种无锁算法。
3.CAS算法的内容
三个操作数:V(当前内存值)、A(旧的预期值)、B(即将要更新的目标值)
CAS执行指令时:当前内存值和旧的预期值进行比较,如果二者相等,就用即将要更新的目标值替换当前内存值。
当多线程用CAS同时更新一个变量时,只有一个线程能更新变量的值,而那些失败的线程不会被挂起,而是会告知失败,还可以再次尝试。
4.CAS的缺点:(1)循环时间长,开销大。比如:当某一方法执行失败时,不会立即结束,而是会继续尝试,但一直尝试失败的话,就会给CPU带来极大的开销。
(2)只能保证一个共享变量的原子操作。
(3)存在ABA问题。
5.ABA问题:CAS中的一个漏洞。CAS 算法实现一个重要前提需要取出内存中某时刻的数据,而在下时刻比较并替换,那么在这个时间差类会导致数据的变化。
比如说一个线程 1从内存中取出 A,同时另一个线程 2 也从内存中取出 A,并且线程2 进行了一些操作将A变成了 B,然后 线程2又将 V 位置的数据变成 A,这时候线程 1进行 CAS 操作发现内存中仍然是 A,然后 线程1操作成功。尽管线程 1的 CAS 操作成功,但是不代表这个过程就是没有问题的。
解决方法:部分乐观锁的实现是通过版本号(version)的方式来解决 ABA 问题,乐观锁每次在执行数据的修改操作时,都会带上一个版本号,一旦版本号和数据的版本号一致就可以执行修改操作并对版本号执行+1 操作,否则就执行失败。因为每次操作的版本号都会随之增加,所以不会出现 ABA 问题,因为版本号只会增加不会减少。