文章目录

  • ​​ABA问题​​
  • ​​AtomicReference原子引用​​
  • ​​AtomicStampedRerference版本号原子引用​​
  • ​​ABA问题的解决​​

ABA问题

ABA问题是cas的缺点之一,由cas引出。

7.互联网大厂高频面试题-ABA问题_版本号


ABA问题:狸猫换太子

7.互联网大厂高频面试题-ABA问题_时间戳_02


多个线程有处理的时间差,会导致ABA问题,中间可以有很多个B(或者是C),只不过首位是一样的,那个慢的线程就认为没改过,会继续修改,返回true,这个过程并不是没有问题的,这就是aba问题。

AtomicReference原子引用

cas是只管开头和尾巴,对的上就ok,在一些环境下是没问题的(如果你不介意的话,只管结果不管过程),但是如果在一些环境里,要求中间不能变就出现问题了。

JUC只提供了原子基础类型,如果我们想用atomicUser这种,JUC就不提供了。但是JUC提供了自己造的方法!

7.互联网大厂高频面试题-ABA问题_时间戳_03


这是一个原子包装的泛型类,丢一个User进去就变成了atomicUser了。

代码示例:

7.互联网大厂高频面试题-ABA问题_代码示例_04


如果你想对某个类进行原子包装,可以参考这个类的写法。

AtomicStampedRerference版本号原子引用

cas存在aba问题,想要解决,最直接的思路就是在刚开始获取的时候,带上时间,这样最后比对的时候也比对时间,哪怕值一样,时间不一样,也对不上,不会修改。

7.互联网大厂高频面试题-ABA问题_版本号_05


7.互联网大厂高频面试题-ABA问题_代码示例_06


上面是2个线程的实例,T2做了中间修改,T1想比对的时候值对的上,但是版本号明显低于最新的,就得去重新获取最新的。

加时间戳的cas类:

7.互联网大厂高频面试题-ABA问题_代码示例_07

ABA问题的解决

7.互联网大厂高频面试题-ABA问题_版本号_08


这个对象维护了一个整形对象的时间戳,他们能够被原子的更新,也就是版本号。

案例复现ABA问题:

7.互联网大厂高频面试题-ABA问题_代码示例_09


结果:

7.互联网大厂高频面试题-ABA问题_时间戳_10


修改成功了,但是发生了ABA问题,中间有猫腻。

ABA问题解决:

7.互联网大厂高频面试题-ABA问题_时间戳_11


7.互联网大厂高频面试题-ABA问题_时间戳_12


第四个参数是修改后的版本号,要+1,执行结果:

7.互联网大厂高频面试题-ABA问题_时间戳_13