『阿里巴巴』Java并发编程之CAS第三篇-CAS的缺点


『阿里巴巴』Java并发编程之CAS第三篇-CAS的缺点
文章图片
『阿里巴巴』Java并发编程之CAS第三篇-CAS的缺点
文章图片
『阿里巴巴』Java并发编程之CAS第三篇-CAS的缺点
文章图片
『阿里巴巴』Java并发编程之CAS第三篇-CAS的缺点
文章图片
『阿里巴巴』Java并发编程之CAS第三篇-CAS的缺点
文章图片
『阿里巴巴』Java并发编程之CAS第三篇-CAS的缺点
文章图片
『阿里巴巴』Java并发编程之CAS第三篇-CAS的缺点
文章图片
Java并发编程之CAS第三篇-CAS的缺点
通过前两篇的文章介绍 , 我们知道了CAS是什么以及查看源码了解CAS原理 。 那么在多线程并发环境中 , 的缺点是什么呢?这篇文章我们就来讨论讨论
本篇是《凯哥(凯哥Java:kagejava)并发编程学习》系列之《CAS系列》教程的第三篇:CAS的缺点有哪些?怎么解决 。
CAS的缺点一:do while循环时间长的话开销大从源码中(见上图) , 我们可以知道do while中的while返回true会一直循环下去(具体分析步骤见上一篇:《Java并发编程之CAS二源码追根溯源》 。 凯哥(凯哥Java:kaigejava)就不在这里赘述了) 。 如果并发量很多的话 , 比如:有十万个线程来并发处理 , 这这种业务下很多线程都会修改共享变量要保证原子性的话 , 循环会很长时间 , 假设每个线程为了保证原子性 , 循环耗时0.001s的话 , 那么十万个线程都这么循环下来 , 对CPU的消耗还是比较大的 。
二:只能保证一个共享变量的原子性从源码中 , 我们知道 Object var1其实就是对象自己 。 拿上一篇文章举的例子来说 , 其实就是atomicInteger自己 , 也就是共享变量 。 CAS的do while只能一个this一个this的比较 。 从这里就可以看出 , CAS只能保证一个共享变量的原子性 。 但是如果用同步锁的话 , 锁是可以锁对象也可以锁代码块 。 锁操作的可以不是一个共享变量 。
三:会出现新的问题:ABA问题何为ABA问题呢?先来看看现实生活的例子:
学校举行运动会 , 标准操场一圈400米 , 现在正在进行1200米比赛 。 1200=400*3.需要跑上三圈 。 小明和小红比赛 , 在刚开始的时候 , 大家都看到小明 , 小红都在起点 , 但是小红速度比小明快2/3 。 这个时候 , 小明爸爸拿着相机拍摄 , 在起点时候 , 拍摄小明 , 3分钟过后 , 我们再来看起点 , 是小红 。 7分钟之后 , 在看起点是小明 。 难道小红就跑了一圈吗?这当然不对 。 小红比小明快 , 当我们第二次看到小明的时候 , 小红其实三圈已经跑完了 。 最终出现的情况就是:小明(小红)小红小明(小红)小明 。 最终获胜的当然是小红
这个例子或者不是很恰当 。 但是凯哥是想通过这个例子告诉大家 , 当线程如果出现这种情况的话 , 会影响到数据结果的 。
如下图:
说明:
A线程执行一次耗时:1分钟
B线程执行一次耗时“29.5s
B线程在A线程执行一次的时间内操作主内存的数据变化为:202020192020
当B线程执行2次操作之后 , 1分钟到了 。 A线程拿着自己工作区copay的副本值i=2020和主内存的值i=2020 。 正好相等 , 这个时候会 , 主内存的共享变量相对于A线程来说 , 是没有变化的 。 但是实际上是有变化的(B线程确实操作过的 。 如上面举例的 , 小红已经跑完三圈了 。 可是小明才跑第二圈呢) , 如果这个时候在操作 , 有可能导致数据出问题(赛跑最终结果是小红赢了 , 而不是小明赢了) 。