面试题总结——乐观锁与悲观锁

面试题总结——乐观锁与悲观锁

 一、乐观锁与悲观锁对比

  1.悲观锁

   共享资源每次只给一个线程使用,其他线程阻塞,需等到当前线程使用完后才能使用(总是假设最坏的情况,每次拿到数据后都会认为别人会修改该数据,因此每次拿数据时都会上锁,阻塞其他人)
   MySQL中的锁机制:行锁,表锁,读锁,写锁;Java中的synchronized和ReentrantLock独占锁。

  2.乐观锁

   总是假设最好的情况,每次拿数据时都认为别人不会修改,因此不会上锁,但在更新时会判断一下在此期间别人有没有更新这个数据,使用版本号机制和CAS算法实现。
   MySQL中的版本号机制;Java中juc.atomic中的原子变量类。

  3.乐观锁(CAS/版本号)的缺点

   ①ABA问题:旧值A先变为了B,又被变为了A,CAS检查时会发现值没有变化->添加版本号;
   ②多个线程的自旋会浪费大量处理器资源:线程CAS过程中在CPU上跑无用指令->自适应自旋/使用Java1.6的全新锁机制;
   ③线程获取锁的公平性:处于自旋状态的线程优先于处于阻塞状态的线程获取到锁,这就有可能导致处于阻塞状态的线程一直获取不到锁->内建锁(synchronized)无法实现公平机制,lock体系可以实现公平锁。

  4.使用场景

   乐观锁:适用于读多写少的场景,冲突很少发生,省去了锁的开销,加大了系统的吞吐量;
   悲观锁:适用于读少写多的场景,经常发生冲突,若采取乐观锁可能会导致上层应用不断地进行retry,降低性能。

 二、乐观锁的实现方式

  1.版本号机制

   数据库中的数据表添加一个数据版本号version字段,表示数据被修改的次数,数据一旦被某事务修改,version就会+1,当事务A要更新数据值时,在读取数据的同时也会读取version值,若对数据进行更新,则version+1,在提交更新时,只有提交版本大于记录当前版本时才能执行更新操作。否则重试更新操作,直到更新成功。

  2.CAS算法

   compare and swap:V(实际的内存值),A(当前线程认为的值),B(拟写入的值),V==A,CAS通过原子方式用新值B来更新V的值,否则不断地重试。

 三、CAS与synchronized使用场景

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值