晓龙吊打面试官系列:CAS算法(乐观锁与悲观锁)

文章目录

  • 一、乐观锁与悲观锁

  • 二、CAS算法


一、乐观锁与悲观锁

在日常的开发中为了保证共享变量的线程安全,大多数程序员的潜意识行为就是为这个共享变量的作用域加锁,就比如常见的使用synchronized关键字来同步代码块。但是简单粗暴的加锁真的是最优解吗?假如被锁住的共享变量并不会被频繁修改,但是synchronized实现的同步无疑会引起线程的堵塞从而降低程序的运行效率。这个时候我们有什么思路可以优化吗?当然可以,JDK的设计者基于这种情况早已给出了很多种解答方式。在JDK1.5后Java通过排它锁,乐观锁等方式来解决共享变量的同步阻塞问题。排他锁之前已经介绍过了,如果有不清楚的同学可以看一下之前的文章来做一下复习:

Lock对象的使用

那么今天的第一个问题来了,什么是乐观锁?

乐观锁就像他的名字一样,他是对于线程之间的竞争保持乐观(乐观锁认为线程之间不存在竞争或存在竞争但不激烈),具体来说就是乐观锁认为对于当前的共享变量每次去读取的时候都会默认其他线程在此期间不会去修改共享变量,因此也不会对该共享变量加锁,直到当前线程结束对变量的操作需要更新变量值得时候会去比较线程运行期间是否有其他线程对该共享变量进行修改,若有则替换最新变量,若没有则直接更新。
通过乐观锁的定义中提到乐观锁认为在当前线程使用共享变量期间其他线程不会或者很少会去修改共享变量的值可以看出乐观锁常用与修饰很少或者不会发生写操作的变量。

与乐观锁相对的就是悲观锁:

悲观锁是一种与乐观锁相反的概念。当一个线程获取到贡献变量的使用权后,该线程会对此共享变量的竞争持悲观状态(存在竞争且竞争激烈),为了防止其他线程会在竞争过程中对变量进行修改,故而每次持有该变量使用权的线程会保证自己对该变量独占(通过加锁防止其他线程修改),在java中的synchronizedreentrantlock等都属于悲观锁。

讲完了乐观锁的概念,新的问题就来了:乐观锁是通过什么方式来实现的?它本身算不算是一种锁?

二、CAS算法

乐观锁的实现依赖于其核心算法:CAS。CAS既 compare and swap,中文可以翻译为比较并交换。字如其意,CAS算法的核心观念就是通过一次比较来判断是否需要更新。
晓龙吊打面试官系列:CAS算法(乐观锁与悲观锁)
那么CAS算法是如何实现的呢?首先在Java的设计者想要解决并发问题之前,就有很多老牌的硬件厂商注意到了这个问题并提出了相应的解决方案。比如著名的inter系列的CPU就可以通过cmpxchg指令来实现CAS,Java的设计者于是在JNI(Java Native Interface,既java本地方法)中直接添加了对相关硬件指令的支持,既CAS在Java的实现是依赖于硬件的
CAS本身是一种无锁算法,他是依赖于三个操作数:内存中的值(V),期望原值(A),新值(B)来实现的。这里我先简单的画个流程图:
晓龙吊打面试官系列:CAS算法(乐观锁与悲观锁)
根据流程图我们可以总结一下CAS算法的设计流程:

  1. 修改一个共享变量前首选去内存中获取此时变量的值并记录为期望值A

  2. 修改此时共享变量的值并记录为更新值B

  3. 在提交变量的更新前再次获取此时内存中该变量的值记为标准值V

  4. 判断V是否与A相等,如果相等则提交更新值B,若不等重新回到流程1

看到这里,相信很多聪明的小伙伴也看出CAS算法的特点了:

CAS算法的优点
1.CAS算法本身是依赖于硬件实现,是一种轻量级的乐观锁,CAS并不会引起线程的堵塞,在线程之间竞争不激烈的情况下性能很高。

CAS算法的缺点

  1. CAS算法如果应用在线程竞争严重的情况下,由于需要频繁并更新期望值A,会因为自旋时间过长引起额外的时间消耗,因此不适合在频繁读写的情况下应用CAS算法。

  2. 由于CAS算法直接比较的是期望值A与标准值V,若发生了ABA问题,CAS无法准确感知。

  3. 仅能保证一个共享变量的原子操作。

ABA问题:
俗话说有图有真相,这里我还是通过一个简单的流程图来解释下什么是ABA问题:
晓龙吊打面试官系列:CAS算法(乐观锁与悲观锁)
ABA问题指的是如果一个值由A变为B再变为A,在使用CAS算法检测时是无法被感知到的。这个时候如果想要解决ABA问题就需要在记录预期值时拼接上此时变量的版本号或者时间戳。

到此,CAS算法相关的知识点就讲述完了,后面有时间的话会详细的讲下锁的分类及锁的升级相关内容,如果觉得有收获的同学希望可以一键三连给博主一些鼓励。
祝一键三连的小伙伴们都可以在之后的日子里找到满意的工作,升职加薪走上人生巅峰!!!


原文始发于微信公众号(青莲明月):晓龙吊打面试官系列:CAS算法(乐观锁与悲观锁)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/107804.html

(0)
青莲明月的头像青莲明月

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!