前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >我司小胖问我,什么是悲观锁 & 乐观锁?

我司小胖问我,什么是悲观锁 & 乐观锁?

作者头像
JavaFish
发布2020-11-19 11:41:38
2530
发布2020-11-19 11:41:38
举报
文章被收录于专栏:狗哥的 Java 世界

悲观锁有 & 乐观锁

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

线程访问资源.jpg

悲观锁

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

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

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

线程 B,进入等待.jpg

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

线程 A 执行完毕,释放锁.jpg

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

线程 B 加锁成功,操作资源.jpg

乐观锁

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

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

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

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

乐观锁获取数据直接操作.jpg

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

乐观锁 CAS 判断.jpg

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

CAS 过程 1.jpg

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

CAS 过程 2.jpg

典型应用

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

  • 悲观锁:synchronized 关键字和 Lock 接口

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

  • 乐观锁:原子类

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

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

  • 典型的 select for update 语句,用的就是悲观锁思想。在提交之前不允许第三方来修改该数据。高并发环境吃不消。
  • 利用 version 字段实现乐观锁,version 代表这条数据的版本。操作数据不需要获取锁,操作完准备更新时。对比版本号是不是和获取数据时一致?是:更新,否:重新计算,再尝试更新。

比如以下的 update 语句:

代码语言:javascript
复制
UPDATE people
SET
name = '狗哥',
    version = 2
WHERE id = 30624700
AND version = 1

使用场景

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

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

  • 悲观锁适用于并发写入多,竞争激烈等场景,这些场景下,悲观锁确实会让得不到锁的线程阻塞,但这些开销是固定的。它可以避免后面更新时的无用反复尝试操作,节约开销。
  • 乐观锁适用于大部分是读取,少部分是修改的场景,也适合虽然读写都很多,但是并发并不激烈的场景。在这些场景下,乐观锁不加锁的特点能让性能大幅提高。

-END-

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-11-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 一个优秀的废人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 悲观锁有 & 乐观锁
    • 悲观锁
      • 乐观锁
        • 典型应用
          • 使用场景
          相关产品与服务
          数据库
          云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档