以下内容纯属个人通俗理解,如有准确或正确,纯属巧合!
CAS(Compare and Swap):这是一个非阻塞式保证原子操作的设计方案。字面意思是比较并且交换,和谁比较?那设置(交换我就理解为设置)什么?
原子操作:值在整个操作过程中,不会发生修改
非阻塞式:不会因为等待获取锁而发生线程切换
比较:用面向过程的方式叙述,第一步:先获取当前时刻的值,第二步,和当前时刻的值比较。虽然都是当前时刻的值,但是两个时刻间是有时间差的(即使感觉起来差距很小),用这两个时刻的值进行比较,是调用equals比较吗?不是,而是“==”。
为什么要比较:两个时刻间,值就有可能被其他线程修改
设置:如果上述比较结果相等,则设置我们想要设置的值;如果不相等,需要循环“比较”和“设置”的逻辑,直到两个时刻的值相等
模拟Integer+1的安全实现:
AtomicReference<Integer> atomicReference= new AtomicReference<Integer>(0);
while (true) {
Integer temp = atomicReference.get();//比较:第一步
if (atomicReference.compareAndSet(temp, temp + 1)) {//比较:第二步,并设置
break;
}
特殊情况:如果用CAS只是为了做加法计算还不会有什么问题,但如果需要捕捉“第一步”和“第二步”两个时刻间的状态变化,那么原子性就有可能被破坏。比如第一步时状态为“A”,在执行到第二步之间,变成了”B”后马上又变回“A”,在第二步中如果不允许有“B”状态发生,那就完蛋了!
解决方法:AtomicStampedReference代替AtomicReference,他对每一个状态都有对应的版本号