乐观锁与悲观锁

Posted wscy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了乐观锁与悲观锁相关的知识,希望对你有一定的参考价值。

乐观锁与悲观锁

悲观锁

假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。如,synchronized关键字使用。

乐观锁

假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。如,CAS(Compare and Swap 比较并交换)。

  • 获得锁后一直持有锁,以防本线程再次申请该锁造成无谓的解锁再加锁开销。
  • 假设没有冲突而去完成同步代码块,如果冲突再循环重试。
  • 采取申请锁失败后不立刻挂起而是稍微等待再次尝试获取,以减少线程因为挂起、阻塞、唤醒而造成的开销。

CAS介绍

  1. CAS 操作中包含三个操作数

    • 需要读写的内存值
    • 进行比较的预期值
    • 拟写入的新值
  2. 原理

    当且仅当预期值和内存值相等时才将内存值修改为新值。首先检查某块内存的值是否跟之前读取时的一样,如不一样则表示期间此内存值已经被别的线程更改过,舍弃本次操作;否则说明期间没有其他线程对此内存值操作,可以把新值设置给此块内存。

  3. 问题

  • 只能保证一个共享变量的原子操作

    JDK提供了AtomicReference类来保证引用对象之间的原子性,可以把多个变量放在一个对象里来进行CAS操作。

  • 循环时间长、开销大

    自旋CAS(不成功,就一直循环执行,直到成功)。

  • ABA问题

    内存值原来是A,后来被一条线程改为B,最后又被改成了A。

    解决方法:引入版本号,更新变量同时修改版本号。

以上是关于乐观锁与悲观锁的主要内容,如果未能解决你的问题,请参考以下文章

协作式原创查漏补缺之乐观锁与悲观锁TODO

乐观锁与悲观锁

面试必备----------------乐观锁与悲观锁

MYSQL悲观锁与乐观锁

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

悲观锁与乐观锁