乐观锁和悲观锁

2022/09/07

乐观锁和悲观锁

乐观锁和悲观锁是两种思想,用于解决并发场景下的数据竞争问题。

  • 乐观锁:乐观锁在操作数据时非常乐观,认为别人不会同时修改数据。因此乐观锁不会上锁,只是在执行更新的时候判断一下在此期间别人是否修改了数据:如果别人修改了数据则放弃操作,否则执行操作。
  • 悲观锁:悲观锁在操作数据时比较悲观,认为别人会同时修改数据。因此操作数据时直接把数据锁住,直到操作完成后才会释放锁;上锁期间其他人不能修改数据。

乐观锁本质上不是锁,而是通过其他方式对数据竞争问题进行求解;悲观锁一般通过上锁的方式解决数据竞争问题,适用的场合更多。

乐观锁两个解决方案:

  • CAS
  • 版本号机制

CAS

compare and swap。

  • 需要读写的内存位置(V)
  • 进行比较的预期值(A)
  • 拟写入的新值(B)

CAS操作逻辑如下:如果内存位置V的值等于预期的A值,则将该位置更新为新值B,否则不进行任何操作。许多CAS的操作是自旋的:如果操作不成功,会一直重试,直到操作成功为止。通过 CPU 的指令实现原子性。

版本号机制

对数据增加一个新的字段,通过对这个字段的解读判断数据是否被修改。其实是类似于 CAS,但是 CAS 关注的是数据的本身,可能存在 ABA 问题,而版本号机制就不会出现该问题。

适用场景

  • 竞争不激烈:乐观锁,对于数据不会进行锁的操作,提升程序运行效率
  • 竞争激烈:悲观锁,虽然锁会有性能损耗,但是竞争激烈情况下,乐观锁的实现会更麻烦

CAS 的缺点

  1. ABA 问题:当前的值已经经历过一次变动,但CAS无感知
  2. 高竞争的开销问题:CAS会不断的尝试,消耗CPU资源
  3. 功能限制:不支持多个变量的操作;需要CPU的支持

Search

    Table of Contents