首页 > 编程知识 正文

解决cas aba问题的方法,cas aba解决办法

时间:2023-05-04 08:20:00 阅读:186793 作者:3328

通过场景,我们来看看多线程的执行场景。

时间点1 :线程1的查询值是否为a

时间点2 :线程2的查询值是否为a

时间点3 :线程2比较并更新值b

时间点4 :线程2的查询值是否为b

时间点5 :线程2比较并更新值a

时间点6 :线程1比较更新值c

在该线程执行场景中,两个线程交替执行。 线程1在时刻6也可以正常进行CAS操作。 尽管在时刻2到时刻6之间发生了意想不到的变化,线程1对这些变化一无所知。 因为对线程1来说a确实还存在。 通常,这种现象被称为ABA问题。

发生了ABA,但线程不知道。 或者,如果链表的头部改变两次后恢复到原始值,并不意味着链表没有改变。

双CAS原理CAS(compareandswap )是指将内存值更新为所需的值,但有条件,内存值必须与期望值相同。 举一个例子,更新存储值v、期望值a、值b,V==A时将v更新为b。

因此,存在多线程时a有可能变更的问题,但之后的线程不知道级别1的变更,可能会发生ABA问题。

三使用解决方法版本号

ABA可以使用JDK合并订购中的AtomicStampedReference和AtomicMarkableReference来解决。

他的原理是AtomicStampedReference和AtomicMarkableReference通过版本号(时间戳)解决了ABA问题,也可以使用版本号(verison )解决ABA。

这意味着乐观锁在每次执行数据修改操作时都有一个版本号。 版本号和数据的版本号一致时,可以执行修正操作,并对版本号执行1操作。 否则,执行将失败。

33558 www.Sina.com/privatestaticclasspairt { finaltreference; final int stamp; privatepair(treference,int stamp ) {this.reference=reference; this.stamp=stamp; }statictpairtof(treference,int stamp ) returnnewpairt ) reference,stamp; }} private volatile PairV pair; publicatomicstampedreference (vinitialref,int initialStamp ) pair=pair.of (initial ref,initialStamp ); }publicvoidset(vnewreference,int newStamp ) { PairV current=pair; if (新参照!=current.reference || newStamp!=current.stamp (this.pair=pair.of ) newreference,newStamp; } publicbooleancompareandset (vexpectedreference,V newReference,int expectedStamp,int newStamp ) { PairV current=pair; returnexpectedreference==current.referenceexpectedstamp==current.stamp () privatestaticfinalsun.misc.unsafe unsafe privatestaticfinallongpairoffset=objectfieldoffset (unsafe,' pair ',AtomicStampedReference.class ); privatebooleancaspair(pairvcmp,PairV val ) return unsafe.compareandswapobject (this,pairOffset,CMP,val ); () ) ) ) )。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。