1、什么是CAS
Compare and Swap(比较交换),通过CAS保证线程对变量的原子性操作,避免其它线程的干扰
CAS是如何执行的
首先涉及到三个参数:要修改的变量、预期的变量值、修改后的变量值
当一个线程要对一个变量进行CAS操作时,会先进行变量值的比对,即要修改的变量值是否与预期的变量值是否一致,一致代表该变量当前没有被其他线程使用,可以进行修改,否则线程会进入自旋锁状态,重复以上操作。
上述过程会引申出如下几个问题:
高并发情况下,多个线程针对同一个变量CAS操作,导致出现很多线程出现自旋锁现象,这无疑增加了CPU的资源消耗,可能出现性能瓶颈。
CAS机制所保证的只是一个变量的原子性操作,而不能保证整个代码块的原子性,如需要保证3个变量共同进行原子性的更新,就不得不使用synchronized了。
ABA问题。
2、什么是ABA问题
因为CAS操作没有使用重量级锁,可能会出现以下情况
线程1进行CAS操作,获取预估值为"A",在线程1进行“比较交换”前,线程2进入并将变量的值由"A"改为“B”,然后又重新改回到"A"并退出,此时对于线程来说,预估值与实际值都为"A",可以进行"比较交换"操作,但是实际上,"A"被修改过。
3、问题解决办法
通过原子引用来解决
原子引用是基于乐观锁的思想,为CAS中的每个操作添加一个版本号,每次执行成功之后,都会对版本号进行+1操作,每次更新数据之前都会对比版本号,观察是否有其他线程进行干扰.如果版本号一制则继续,不一致进入自旋.
Java中提供了AtomicStampedReference类来实现原子引用并可以设置版本号