当前位置:首页 >探索 >并发编程:Atomic类与悲观锁和乐观锁 观锁观锁那么尽管修改过两次

并发编程:Atomic类与悲观锁和乐观锁 观锁观锁那么尽管修改过两次

2024-05-16 21:51:51 [百科] 来源:避面尹邢网

并发编程:Atomic类与悲观锁和乐观锁

作者:日拱一卒程序猿 开发 前端 CAS都是并发编程基于“值”来做比较的。但如果另外一个线程把变量的类悲值从A改为B,再从B改回 到A,观锁观锁那么尽管修改过两次,和乐可是并发编程在当前线程做CAS操作的时候,却会因为值没变而认为数据没有被其他 线程修改过,类悲这就是观锁观锁所谓的ABA问题。

一、和乐悲观锁与乐观锁

对于悲观锁,并发编程认为数据发生并发冲突的类悲概率很大,读操作之前就上锁。观锁观锁synchronized关键字,和乐后面 要讲的并发编程ReentrantLock都是悲观锁的典型。

对于乐观锁,类悲认为数据发生并发冲突的观锁观锁概率比较小,读操作之前不上锁。等到写操作的时候,再判 断数据在此期间是否被其他线程修改了。如果被其他线程修改了,就把数据重新读出来,重复该过程; 如果没有被修改,就写回去。判断数据是否被修改,同时写回新值,这两个操作要合成一个原子操作, 也就是CAS ( Compare And Set )。

并发编程:Atomic类与悲观锁和乐观锁 观锁观锁那么尽管修改过两次

AtomicInteger的实现就是典型的乐观锁。

并发编程:Atomic类与悲观锁和乐观锁 观锁观锁那么尽管修改过两次

AtomicInteger的实现就用的是“自旋”策略,如果拿不到锁,就会一直重试。

并发编程:Atomic类与悲观锁和乐观锁 观锁观锁那么尽管修改过两次

二、ABA问题与解决办法

到目前为止,CAS都是基于“值”来做比较的。但如果另外一个线程把变量的值从A改为B,再从B改回 到A,那么尽管修改过两次,可是在当前线程做CAS操作的时候,却会因为值没变而认为数据没有被其他 线程修改过,这就是所谓的ABA问题。

举例来说: 小张欠小李100块,约定今天还,给打到网银。 小李家的网银余额是0,打过来之后应该是100块。 小张今天还钱这个事小李知道,小李还告诉了自己媳妇。 小张还钱,小李媳妇看到了,就取出来花掉了。 小李恰好在他媳妇取出之后检查账户,一看余额还是0。 然后找小张,要账。

这其中,小李家的账户余额从0到100,再从100到0,小李一开始检查是0,第二次检查还是0,就 认为小张没还钱。 实际上小李媳妇花掉了。 ABA问题。 其实小李可以查看账户的收支记录。

要解决 ABA 问题,不仅要比较“值”,还要比较“版本号”,而这正是 AtomicStampedReference做的事情。

责任编辑:武晓燕 来源: 今日头条 Atomic类乐观锁悲观锁

(责任编辑:时尚)

    推荐文章
    热点阅读