悲观锁与乐观锁的实现(详情图解) (3)

Java中真正的CAS操作调用的native方法
因为整个过程中并没有“加锁”和“解锁”操作,因此乐观锁策略也被称为无锁编程。换句话说,乐观锁其实不是“锁”,它仅仅是一个循环重试CAS的算法而已,但是CAS有一个问题那就是会产生ABA问题,什么是ABA问题,以及如何解决呢?

ABA 问题:
如果一个变量V初次读取的时候是A值,并且在准备赋值的时候检查到它仍然是A值,那我们就能说明它的值没有被其他线程修改过了吗?很明显是不能的,因为在这段时间它的值可能被改为其他值,然后又改回A,那CAS操作就会误认为它从来没有被修改过。这个问题被称为CAS操作的 "ABA"问题。

ABA 问题解决:
我们需要加上一个版本号(Version),在每次提交的时候将版本号+1操作,那么下个线程去提交修改的时候,会带上版本号去判断,如果版本修改了,那么线程重试或者提示错误信息~

四、如何选择

悲观锁阻塞事务,乐观锁回滚重试,它们各有优缺点,不要认为一种一定好于另一种。像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去锁的开销,加大了系统的整个吞吐量。

但如果经常产生冲突,上层应用会不断的进行重试,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。

注意点:

1、乐观锁并未真正加锁,所以效率高。一旦锁的粒度掌握不好,更新失败的概率就会比较高,容易发生业务失败。

2、悲观锁依赖数据库锁,效率低。更新失败的概率比较低。

五、总结

这篇文章讲解了悲观锁与乐观锁的区别,以及实现场景,不管是悲观锁还是乐观锁都是人们定义出来的概念,是一种思想,如何有有疑问或者问题的小伙伴可以在下面进行留言,小农看到了会第一时间回复大家,谢谢,大家加油~

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

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