整理笔记:多线程 并发 CAS问题

整理笔记:多线程 并发 CAS问题

使用锁机制会遇到的问题?

  1. 在多线程竞争下,上锁和释放锁都会导致比较多的上下文切换和调度延时,从而影响性能。
  2. 一个线程持有锁会导致其他所有需要此锁的线程挂起。
  3. 如果高优先级的线程要等低优先级的线程释放后再执行,这样就引起优先级混乱,从而也影响性能。
  4. synchronized是独占锁,会导致其他所有需要锁的线程挂起,等待持有锁的线程释放锁。独占锁是一种悲观锁。解决这个问题需要用到乐观锁的概念。
    所谓乐观锁:每次不加锁而是假设没有冲突而去完成某项操作,如果遇到冲突造成失败就会去重试该操作,直到成功为止。

乐观锁的机制就是CAS

CAS

使用CAS的目的

乐观锁的机制就是CAS,当多个线程同时对某个资源进行CAS操作,只能有一个线程操作成功,但是并不会阻塞其他线程,因为其他线程只会收到操作失败的信号。
因此,使用CAS就是利用CPU的CAS指令,同时借助JNI来完成Java的非阻塞算法。其他原子操作都是利用类似的特性完成的。而整个J.U.C都是建立在CAS之上的,因此对于synchronized阻塞算法,J.U.C在性能上有了很大提升。

CAS的三大操作数:V ,A,B

(1)V:内存地址V
(2)A:预期原值A
(3)B:新值B

操作流程

先比较内存地址V处的值与预期原值A是否相等,如果相等就将内存地址V处更新为新值B。
在配合循环使用时,若CAS操作失败,会循环执行或到达某个终止处。此操作配合循环使用时。又称为“自旋锁”的实现方式。

使用CAS存在的问题?

(1)ABA问题:

线程操作时,先将内存的V中的A值改成B值,然后又将值B更新为值A,导致最终CAS判断内存V处的值并没有发生变化,认为更新没有成功,但是实际上已经更新过了。

一个形象的比喻帮助理解:

曾经看到过有个老师这么比喻,感觉挺有意思的,好像说的也挺那么回事:程序员二币有个很漂亮的女朋友阿绿,有一天二币被通知要出差一个月,这一个月期间阿绿和他们隔壁老王勾搭上了,并且发生了不可描述的事情,一个月后二币出差回来了,他看到自己的女朋友阿绿依旧没有任何变化依旧很漂亮,但是其实阿绿已经不是阿绿已经被老王更新迭代过了。

解决ABA问题常见的办法

  • 加时间戳。
  • 加版本号

(2)循环时间长开销大:

不断的循环重试,如果线程较多,资源抢占激烈,而成功率较低的情况下,循环越多消耗的资源就越多。
解决这种问题:常见的是设置最大次数,如果循环至最大次数仍没有成功则自动放弃,避免无限循环。

(3)只能保证一个共享变量的原子操作:

CAS最多只能操作一个共享变量,而单体的效率低。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值