面试题:什么是悲观锁 & 乐观锁?


Java 面试准备

准确的说这里又分为两部分:

   1、Java 刷题

   2、算法刷题

Java 刷题:此份文档详细记录了千道面试题与详解;

很多人感叹“学习无用”,实际上之所以产生无用论,是因为自己想要的与自己所学的匹配不上,这也就意味着自己学得远远不够。
无论是学习还是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。

以下学习资料均免费放送,最后祝愿各位顺利拿到心仪的offer! 

悲观锁有 & 乐观锁

首先,悲观锁与乐观锁是根据操作时是否锁住资源来判别的。悲观锁获取到锁时,必须要锁住资源;乐观锁则不会。一开始两线程争抢锁:


悲观锁

悲观锁之所以悲观,那是因为它觉得如果不锁住这个资源,别的线程就会来争抢,造成数据结果错误,所以悲观锁为了确保结果的正确性,会在每次获取并修改数据时,都把数据锁住,让其他线程无法访问该数据,这样就可以确保数据内容万无一失,从这点看悲观锁特别稳。

下面通过几张图,大概就能明白悲观锁的执行过程了:

接上面场景,如果 A 拿到锁,正在操作资源,B 就只能进入等待。


直至 A 执行完毕释放锁,CPU 唤醒等待此锁的线程 B。


线程 B 获取到了锁,就可以对同步资源进行自己的操作。这就是悲观锁的操作流程。


乐观锁

乐观锁顾名思义,比较乐观。相比于悲观锁,它是不锁住资源的,因为它觉得自己在操作资源时并不会有其他线程干扰。

因此,为了保障数据的正确性。它在操作之前,会先判断在自己操作期间,其他线程是否有操作。如果没有,直接操作;如果有,则根据业务选择报错或者重试。

下面来看看,乐观锁的执行过程:

乐观锁的这把锁,其实就是依赖的 CAS (compare and swap:比较并交换)算法。所以,它在操作资源之前并不需要获得锁,直接读取资源到自己的工作内存内操作:


操作完成,准备更新资源时。就会触发 CAS 算法,判断资源是否被其他线程修改过。


没有修改过,直接更新,线程执行完毕。


被修改过,根据业务逻辑走下一步,是重试还是报错?


典型应用

值得注意的是,不管是在 Java 还是数据库中都用到了。悲观锁、乐观锁的概念,只是实现方式稍有不同。下面介绍下 Java 中的悲观、乐观锁:

悲观锁:synchronized 关键字和 Lock 接口
这两够经典的,synchronized 必须要获取 mintor 锁才能进去操作资源;Lock 接口也是,必须显示调用 lock 才能操作资源。必须取到锁才能进行操作,这就是悲观锁的思想。

乐观锁:原子类
这类应该很常用,比如用作线程间的计数器。典型如 AtomicInteger 类在进行运算时,就使用了乐观锁的思想。使用 compareAndSet 方法更新数据,更新失败则重试。

数据库中的悲观、乐观锁:

典型的 select for update 语句,用的就是悲观锁思想。在提交之前不允许第三方来修改该数据。高并发环境吃不消。

利用 version 字段实现乐观锁,version 代表这条数据的版本。操作数据不需要获取锁,操作完准备更新时。对比版本号是不是和获取数据时一致?是:更新,否:重新计算,再尝试更新。

比如以下的 update 语句:

UPDATE peopleSETname = '狗哥',    version = 2WHERE id = 30624700AND version = 1

使用场景
说了这么久,悲观锁乐观锁的区别我知道了。那这两种锁在啥样的场景下使用呢?

有人说悲观锁比乐观锁消耗大,因为悲观要锁、乐观不要锁(注意,这里我说不要是实际没锁住资源,它的锁其实是 CAS 算法)。是的,如果并发量很小的情况下,悲观锁确实比乐观锁消耗大。但如果并发量很高,导致乐观锁一直在重试,这时它消耗的资源比固定开销的悲观大,也是说不定的。

悲观锁适用于并发写入多,竞争激烈等场景,这些场景下,悲观锁确实会让得不到锁的线程阻塞,但这些开销是固定的。它可以避免后面更新时的无用反复尝试操作,节约开销。

乐观锁适用于大部分是读取,少部分是修改的场景,也适合虽然读写都很多,但是并发并不激烈的场景。在这些场景下,乐观锁不加锁的特点能让性能大幅提高。

#面试##笔试题目##Java##笔记##技术栈##求offer##后端开发#
全部评论
明白了,悲观锁据就是锁住这个资源,以保证正确性
点赞 回复 分享
发布于 2022-06-28 14:39

相关推荐

05-12 11:09
已编辑
门头沟学院 后端
SmileDog12138:没必要放这么多专业技能的描述。这些应该是默认已会的,写这么多行感觉在凑内容。项目这块感觉再包装包装吧,换个名字,虽然大家的项目基本都是网上套壳的,但是你这也太明显了。放一个业务项目,再放一个技术项目。技术项目,例如中间件的一些扩展和尝试。
点赞 评论 收藏
分享
评论
3
10
分享

创作者周榜

更多
牛客网
牛客企业服务