乐观锁和悲观锁的简单理解

一、悲观锁

每次读取数据时认为其他线程会修改这个数据,所以每次读的时候都会加锁,实现悲观锁需要使用数据库的锁机制
1.共享锁
2.排他锁
3.行锁

① 共享锁

共享锁也称为S锁,事务A获取S锁后,事务B也可以获得S锁,但获得该锁的事务只能读不能写
举个简单的例子来说就是租房子:很多人预约了同一个时间要去看同一个房子,这时一个人相当于一个事务,看房就相当于S锁,我可以来看房,别人也可以来看房这就是 共享锁。

② 排他锁

排他锁又称为X锁,事务A获得X锁后,事务B便不可以再获得S锁和X锁,事务A可以读写数据,直到事务A释放该锁,其他事务才能获得该锁。同样用上面的租房例子来说就是:我和中介签订了租房合同,其他人就不能再来看这个房子了,而我可以随意进出,其中签合同就是X锁,直到我的租期到了将钥匙还回去其他人才能来看房

注意这其中有个问题,当在读加锁的模式下,任何线程都可以对其进行读加锁的操作,但所有试图进行写加锁操作的线程都会被阻塞。直到所有读线程解锁。但是当读线程太多时,写线程一直被阻塞显然是不对的,所以一个线程想要对其进行写加锁时,就会阻塞读加锁,先让写加锁线程加锁。

悲观锁缺点
由于读写都需要加锁,会增大CPU的开销,拉低了执行效率

二、乐观锁

乐观锁是一种思想,不是实际意义上的加锁,认为当一个线程修改数据时认为其他线程不会修改该数据,但是在更新数据的时候会去判断以下其他线程是否修改了数据。通过版本来判断,如果数据被修改了就拒绝更新,之所以叫乐观锁是因为并没有加锁。

以下是2种实现方式

① 版本控制

乐观锁的实现十分简单,给表中加一个version字段。
例如:A和B分别使用同一个银行账户消费,原本账户余额为100元

  1. A要消费50元,此时A拿到的版本号为1
  2. 正准备修改时B进来读取了版本1的数据
  3. B要消费20元,此时B拿到的也是版本1
  4. 然后A执行了修改操作,余额变为50元,并将版本号改为2
  5. B拿到的版本1的数据还认为余额是100元,减去20剩下80元,并将拿到版本号改为2
  6. B再去执行修改操作,发现已经存在版本号为2的数据,说明已经被修改过了,就会驳回此次修改
  7. B重新去数据库读数据和版本再执行修改,直到修改成功
② CAS算法

CAS是英文单词CompareAndSwap的缩写,中文意思是:比较并替换。
CAS需要有3个操作数:内存地址V,旧的预期值A,即将要更新的目标值B。

CAS指令执行时,当且仅当内存V的值与预期值A相等时,将内存地址V的值修改为B,否则就什么都不做。整个比较并替换的操作是一个原子操作。CAS是乐观锁技术,当多个线程尝试使用CAS同时更新同一个变量时,只有其中一个线程能更新变量的值,而其它线程都失败,失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次尝试。

乐观锁缺点

ABA问题
线程1读取到的数据为666;
线程2将该数据修改为999;
线程2将该数据修改为666;
线程1对数据进行CAS操作
由于内存中数据仍然为666,因此CAS操作成功,但实际上该数据已经被线程2修改过了。这就是ABA问题。
表面上看上去似乎没什么影响,但是在特殊情况下,ABA却会带来隐患,例如栈顶问题:一个栈的栈顶经过两次(或多次)变化又恢复了原值,但是栈可能已发生了变化,对于此问题引入版本号就可以解决(AtomicStampedReference类)。比较时不仅比较内存中的数据有没有改便变,还比较版本号是不是一致,如果是就进行CAS操作。

三、总结

悲观锁阻塞事务,乐观锁回滚重试,它们各有优缺点,不要认为一种一定好于另一种。像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行重试,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。

乐观锁和悲观锁的简单理解相关推荐

  1. [初级]深入理解乐观锁与悲观锁

    2019独角兽企业重金招聘Python工程师标准>>> 在数据库的锁机制中介绍过,数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔 ...

  2. 深入理解乐观锁与悲观锁

    在数据库的锁机制中介绍过,数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性. 乐观并发控制(乐观锁)和悲观并发控制(悲 ...

  3. mysql乐观锁与事务_[数据库事务与锁]详解七: 深入理解乐观锁与悲观锁

    注明: 本文转载自http://www.hollischuang.com/archives/934 在数据库的锁机制中介绍过,数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库 ...

  4. 深入理解乐观锁与悲观锁(实战)

    在数据库的锁机制中介绍过,数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性. 乐观并发控制(乐观锁)和悲观并发控制(悲 ...

  5. 一文彻底理解乐观锁与悲观锁

    通过阅读本文可以获得什么 1.什么是乐观锁? 2.乐观锁实现方式都有什么? 3.乐观锁优缺点有哪些? 4.乐观锁适用场景? 5.什么是悲观锁? 6.悲观锁实现方式有哪几种? 7.悲观锁优缺点? 8.悲 ...

  6. 数据库---通俗理解乐观锁和悲观锁

    mysql数据库和java中有关乐观锁和悲观锁的概念以及实现方式 在数据库的锁机制中,数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时在存储数据库中同一数据时不破坏事物的隔离性和统一性 ...

  7. 浅谈对于乐观锁和悲观锁的理解

    今儿回忆了一下关于乐观锁和悲观锁的知识,要唠唠这两个点,那先得知道什么是锁? 1.锁的定义:锁是一种互斥的机制,在多线程环境中实现对资源的协调与控制,凡是有资源被多线程共享,涉及到修改的情况就要考虑锁 ...

  8. 乐观锁与悲观锁深入学习理解

    乐观锁与悲观锁深入学习理解 一.乐观锁和悲观锁 悲观锁 乐观锁 二.两种锁的使用场景 悲观锁 乐观锁 三.乐观锁实现方式 四.乐观锁的缺点 五.总结 参考文献 一.乐观锁和悲观锁 乐观锁和悲观锁并不是 ...

  9. 乐观锁、悲观锁简单分析,回忆旧(新)知识...

    2019独角兽企业重金招聘Python工程师标准>>> 今天被人问了下乐观锁和悲观锁,突然在脑子里好模糊,但又感觉以前很熟悉的东西竟然忘得这么干净.所以恶补加记录一下. 乐观锁和悲观 ...

最新文章

  1. 如何利用azMan (Authorization Manager) 实现 role-based的安全验证机制
  2. DZX2无法读取会员短消息
  3. 转 Windows Mobile 开发工具和资源 黎波
  4. linux centos密码忘记,CentOS忘记root密码的解决办法
  5. 解决iphone填写表单时,表单项获取焦点时往下拉屏,导致顶部标题栏下滑错位...
  6. git 使用writer_GitHub - Vpredictor/WriterFly: [QT/C++] 写作天下,为作家创造世界而生,执云作笔,诉尽平生意。...
  7. What is the difference between a domain and web hosting? (域名和虚拟主机)
  8. vue + vue-router +axios + element UI + PHP + CodeIgniter + Mysql 项目管理系统
  9. maven:《Maven实战》读书笔记
  10. 最新传奇游戏公司网站模板源码+带手机端/易优CMS内核
  11. C盘清理方法——基于spacesniffer软件和PatchCleaner软件
  12. java excelhandle oschina,基于alibab的easyexcel进行excel表的导出(可自定义handler去设计excel格式)...
  13. net start mysql无法启动数据库的解决办法
  14. NOI前的做题计划记录
  15. 视频会议十大开源项目
  16. Element引入Iconfont(阿里巴巴矢量图标库)第三方图标库
  17. 新手做电商直播带货怎么和快递合作谈价格
  18. The 9-th BIT Campus Programming F. 狂乱(背包)
  19. 批处理 检测U盘插入并自动备份文件
  20. sqlite奇怪错误SQL logic error

热门文章

  1. linux 多核cpu监控,Linux 下多核CPU知识
  2. 什么是软件验收测试?如何获取软件验收测试报告
  3. Incompatible types
  4. windows下使用控制台打开conda虚拟环境
  5. 如何建立英文字符的哈希表
  6. wpf中图片滚动效果demo_如何将商品视觉化运用到店铺中?小型文具店货架效果图文具店货架图片...
  7. c语言0x1234占两个字节,C语言考试必考知识点
  8. WPF MVVM架构 程序退出右下角托盘图标简单解决方案
  9. spring的actuator健康监测配置
  10. Windows下如何将文件打包压缩成 .tar.gz格式