搞懂多线程(七)之CAS

一、概念

CAS(compare and swap):中文翻译成比较并交换,实现并发算法时常用到的一种技术。

它包含三个操作数:内存位置预期原值更新值

执行CAS操作的时候,将内存位置的值与预期原值比较:

  • 如果相匹配,那么处理器会自动将该位置值更新为新值

  • 如果不匹配,处理器不做任何操作,多个线程同时执行CAS操作只有一个会成功

可以结合乐观锁进行理解。

二、UnSafe类

UnSafe类:是CAS的核心类,由于Java 方法无法直接访问底层 ,需要通过本地(native)方法来访问

UnSafe相当于一个后门,基于该类可以直接操作特定的内存数据

UnSafe类在于sun.misc包中,其内部方法操作可以向C的指针一样直接操作内存,因为Java中CAS操作依赖于UnSafe类的方法

注意:UnSafe类中所有的方法都是native修饰的,也就是说UnSafe类中的方法都是直接调用操作底层资源执行响应的任务

底层核心实现逻辑是汇编指令cmpxchg ,多核cpu下就是加锁实现并发问题(加锁就是我在干活的时候,其他人排队,即阻塞

三、存在的问题

1.循环对CPU开销很大

  • 我们可以看到getAndInt方法执行时,有个do while

  • 如果CAS失败,会一直进行尝试。如果CAS长时间一直不成功,可能会给CPU带来很大的开销

2.导致ABA问题

CAS算法实现一个重要前提需要取出内存中某时刻的数据并在当下时刻比较并替换,那么在这个时间差类会导致数据的变化

比如说一个线程1从内存位置V中取出A,这时候另一个线程2也从内存中取出A,并且线程2进行了一些操作将值变成了B,然后线程2又将V位置的数据变成A,这时候线程1进行CAS操作发现内存中仍然是A,预期OK,然后线程1操作成功。

尽管线程1的CAS操作成功,但是不代表这个过程就是没有问题的。

解决方法:可以使用AtomicStampedReference来通过版本号的方法解决