Java并发编程之CAS第三篇-CAS的缺点及解决办法

Java并发编程之CAS第三篇-CAS的缺点

通过前两篇的文章介绍,我们知道了CAS是什么以及查看源码了解CAS原理。那么在多线程并发环境中,的缺点是什么呢?这篇文章我们就来讨论讨论

本篇是《凯哥(凯哥Java:kagejava)并发编程学习》系列之《CAS系列》教程的第三篇:CAS的缺点有哪些?怎么解决。

Java并发编程之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分钟之后,在看起点是小明。难道小红就跑了一圈吗?这当然不对。小红比小明快,当我们第二次看到小明的时候,小红其实三圈已经跑完了。最终出现的情况就是:小明(小红)小红小明(小红)小明。最终获胜的当然是小红

这个例子或者不是很恰当。但是凯哥是想通过这个例子告诉大家,当线程如果出现这种情况的话,会影响到数据结果的。

如下图:

Java并发编程之CAS第三篇-CAS的缺点及解决办法

 

说明:

A线程执行一次耗时:1分钟

B线程执行一次耗时“29.5s

B线程在A线程执行一次的时间内操作主内存的数据变化为:202020192020

当B线程执行2次操作之后,1分钟到了。A线程拿着自己工作区copay的副本值i=2020和主内存的值i=2020。正好相等,这个时候会,主内存的共享变量相对于A线程来说,是没有变化的。但是实际上是有变化的(B线程确实操作过的。如上面举例的,小红已经跑完三圈了。可是小明才跑第二圈呢),如果这个时候在操作,有可能导致数据出问题(赛跑最终结果是小红赢了,而不是小明赢了)。

所谓的ABA就是:在某个监控点的时候数据是A,当过了时间N之后,在监控的时候还是A。但是在时间N的这段时间内,监控点的数据有可能不是A了,变成过B。这样就更容易理解了吧。

ABA问题演示代码:

Java并发编程之CAS第三篇-CAS的缺点及解决办法

 

代码说明:

初始的时候,给了变量值为2020.也就是V=2020.如上图1

在经过线程A一顿猛如虎的操作之后,搞出来2020,2021,2020.ABA的效果处理。如上图2.

Sleep了1秒是为了让线程A完成ABA操作的。

然后,线程2在拿着自己副本的变量值A=2020,和主内存V进行比较。发现一致,就更新了2019.

运行结果如下图:

Java并发编程之CAS第三篇-CAS的缺点及解决办法

 

从运行结果来看,线程2也更新成功了。但是,这样是不对的。因为我们已经知道线程A对共享变量操作过了。那么针对CAS的这些缺点,应该怎么解决呢?欢迎继续学习下一篇。凯哥将介绍三个怎么解决。以及会讲解原子引用、时间戳原子引用两个问题。

CAS缺点解决办法 一:循环长,开销大解决方案

解决思路:ConcurrentHashMap(后面凯哥也会详细介绍的)类似的方法。当多个线程竞争时,将粒度变小,将一个变量拆分为多个变量,达到多个线程访问多个资源的效果,最后再调用sum把它合起来。

二:一个共享变量的解决方案

因为CAS只能一个共享变量一个共享变量的处理。如果想要处理类是代码块或者对象的。可以使用同步锁或者是多个变量放到一个对象里面。然后在CAS。因为在JUC包下,有支持对象的原子类,如:AtomicReference(原子引用类)。

原子引用

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zypsxw.html