为了账号安全,请及时绑定邮箱和手机立即绑定

【九月打卡】第17天 不可不说的“锁”事【种类繁多,如何一一突破?】

标签:
Java

课程名称:玩转Java并发工具,精通JUC,成为并发多面手
课程章节:第5章 不可不说的“锁”事【种类繁多,如何一一突破?】
课程讲师: 悟空

课程内容

二、锁的分类

图片描述

  • 这些分类,是从各种不同角度出发去看的
  • 这些分类并不是互斥的,也就是多个类型可以并存:有可能一个锁同时属于两种类型
  • 比如ReentrantLock既是互斥锁,又是可重入锁

三、乐观锁和悲观锁

3.1、为什么会诞生非互斥同步锁——互斥同步锁的劣势

  • 阻塞和唤醒会带来性能劣势,性能损耗主要发送在线程的阻塞和唤醒阶段(上下文切换等),乐观锁最主要解决的就是性能问题,乐观锁不需要将线程挂起
  • 永久阻塞:如果持有锁的线程被永久阻塞,比如遇到了无限循环、死锁等活跃性问题,那么等待该线程释放锁的那几个悲催的线程,将永远得不到执行。
  • 优先级反转

3.2、什么是乐观锁和悲观锁

  • 是否锁住资源的角度分类
悲观锁
  • 如果我不锁住这个资源,别人就会来争抢,就会造成数据结果错误,所以每次悲观锁为了确保结果的正确性,会在每次获取并修改数据时,把数据锁住,让别人无法访问该数据,这样就可以确保数据内容万无一失。
  • Java中悲观锁的实现就是synchronized和Lock相关类
乐观锁
  • 认为自己在处理操作的时候不会有其他线程来干扰,所以并不会锁住被操作对象。
  • 在更新的时候,去对比在我修改期间数据有没有被其他人改变过:如果没被改变过,就说明真的只有我自己在操作,那我就正常去修改数据
  • 如果数据和我一开始拿到的不一样了,说明其他人在这段时间内改过数据,那我就不能继续刚才的更新数据过程了,我会选择放弃、报错、重试等策略
  • 乐观锁的实现一般都是利用CAS算法来实现的。CAS的核心原理就是我可以在一个原子操作内把数据对比并且修改,在此期间是没有人可以打断我的。

3.3、典型例子

  • 悲观锁:synchronized和lock接口
  • 乐观锁的典型例子就是原子类并发容器,底层实现利用到了乐观锁的思想。
  • Git:Git就是乐观锁的典型例子,当我们往远端仓库push的时候,git会见擦汗远端仓库的版本号是不是领先于我们现在的版本, 如果远程仓库的版本号和本地的不一致,就表示有其他人修改了远端代码,我们这次提交就失败
    ;如果远端和本地版本号一致,我们就可以顺利提交版本到远端仓库
  • Git不适合用悲观锁,否则公司倒闭
  • select for update就是悲观锁
  • 用version控制数据库就是乐观锁
  1. 添加一个字段 lock_version
  2. 先查询这个更新语句version:select * from table
  3. 然后update set num=2,version=version+1 where version=1 and id =5
  4. 如果version被更新了等于2,不一样就会更新出错。这就是乐观锁的原理。

课程收获

今天学习了锁的相关知识。再接再厉~
图片描述

点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消