ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

乐观锁以及悲观锁

2020-03-24 20:51:04  阅读:261  来源: 互联网

标签:ABA 变量 以及 CAS 位置 乐观 线程 悲观 操作


悲观锁

       假设是每次获取数据都认为会被其他线程修改,每次来操作数据(可读、可写)的时候都会加锁;悲观锁的实现是Synchronized。

悲观锁存在问题:

1、多线程竞争,引起性能问题 (锁的释放和获取需要上下文切换和调度等)

2、一个线程获取锁会导致其他线程被挂起(阻塞)

乐观锁

       假设对数据的操作一般都不会发生冲突,读取操作时,不会加锁,在对数据进行变更操作是,才来检测当前的数据是否发送冲突,发生冲突返回错误信息,让用户类决定如何做乐观锁阐述的思路,主要有两个步骤操作:冲突检测和数据更新,该方式的实现就是CAS是乐观锁。

CAS

      CAS(Compare And Set),多个线程通过CAS尝试修改同一个变量,只有一个线程在同一时刻进行修改,而其他的操作失败,失败的线程不会挂起,告诉失败的线程可以再次尝试。

      CAS操作涉及到三个操作数:需要读写的内存位置(V)、进行比较的预期的原值(A)、待写入的新值(B)。

 

    第一步:获取位置V的值A   

    第二步:将A和B同时进行处理,将A和位置V存储值进行比较,如果相等,则将位置V的值由A变更为B,则操作成功;不相等,则不变更为B,继续循环进入第一步。

    如果内存位置V的值与预期原值A相匹配,那么处理器会自动将该位置值更新为新值B.否则处理器不做任何操作。无论哪种情况,它都会在CAS指令之前返回该位置的值。(在 CAS的一些特殊情况下将仅返回CAS是否成功,而不提取当前值。) CAS有效地说明了“我认为位置V应该包含值A;如果包含该值,则将B放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可。

 

CAS引发的ABA问题

假设存在以下线程操作序列:

1、线程1从内存位置V中取得A

2、线程2从内存位置V获取A

3、线程2进行一些操作,将A修改为其他的结果,将B修改为A

4、线程2将A再次写入到位置V

5、线程1进行CAS操作,发现位置V中任然是A,直接修改为B,操作成功

6、尽管线程1操作成功,但并不该表该过程没有问题,对于线程1而言,线程2 的修改以导致数据丢失

举例说明ABA问题:

1、现有一个单向链表实现的堆栈,栈顶为A,线程1获取到A.next为B,线程1希望通过CAS操作将栈顶替换为B

2、在线程1执行CAS操作之前,线程2来执行,将A、B出站,在依次入栈D、C、A,而对象B处于游离状态

3、此时线程1执行CAS操作,检测栈顶为A,CAS成功执行,栈顶为B,实际是B.next = null,此时堆栈只有一个B,C和D组成的链表不在堆栈中,C\D 被丢弃了

ABA问题的解决方案

ABA问题的解决需要使用版本号,在变量前加上版本号,每次变量的变更操作版本号+1,那么A-B-A就变成1A-2B-3A。

使用CAS会引发的问题

CAS虽然比Java中提供的锁的开销小,但是存在问题

  1. ABA问题 ABA问题通过版本号解决
  2. 循环时间长开销大     自旋CAS如果长时间不成功,会给CPU带来非常大的执行开销。如果JVM能支持处理器提供的pause指令那么效率会有一定的提升,pause指令有两个作用,第一它可以延迟流水线执行指令(de-pipeline),使CPU不会消耗过多的执行资源,延迟的时间取决于具体实现的版本,在一些处理器上延迟时间是零。第二它可以避免在退出循环的时候因内存顺序冲突(memory order violation)而引起CPU流水线被清空(CPU pipeline flush),从而提高CPU的执行效率。
  3. 只能保证一个共享变量的原子操作     当对一个共享变量执行操作时,我们可以使用循环CAS的方式来保证原子操作,但是对多个共享变量操作时,循环CAS就无法保证操作的原子性,这个时候就可以用锁,或者有一个取巧的办法,就是把多个共享变量合并成一个共享变量来操作。比如有两个共享变量i=2,j=a,合并一下ij=2a,然后用CAS来操作ij。从Java1.5开始JDK提供了AtomicReference类来保证引用对象之间的原子性,你可以把多个变量放在一个对象里来进行CAS操作

标签:ABA,变量,以及,CAS,位置,乐观,线程,悲观,操作
来源: https://www.cnblogs.com/128-cdy/p/12554511.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有