面试题:乐观锁和悲观锁

(1)乐观锁和悲观锁概念介绍

介绍乐观锁和悲观锁,可以先理解一下,乐观、悲观两个概念。

    乐观锁对应于生活中乐观的人总是想着事情往好的方向发展。 悲观锁对应于生活中悲观的人总是想着事情往坏的方向发展。

乐观锁和悲观锁是两种思想,不局限在某种编程语言或者数据库。

乐观锁概念

乐观锁在操作数据的时候,非常乐观,都认为别人不会同时修改数据,所以乐观锁在更新数据之前,都不会对数据进行加锁,只有当执行更新数据操作时候,再去判断数据是否被修改,如果数据被修改了,就放弃被当前修改操作。

悲观锁概念

悲观锁在操作数据时候,比较悲观,都认为别人会和自己同时修改数据,所以悲观锁操作数据时候,会直接给数据上锁,不让别人操作,只有自己操作完成后,才释放锁。

(2)乐观锁和悲观锁使用场景

乐观锁使用场景

乐观锁适用于读多写少的情况下,即:读数据多余写数据的时候,可以考虑使用乐观锁。

注意:乐观锁本身是不加锁的,只是会在更新数据时候判断数据是否变化。

悲观锁使用场景

悲观锁适用于写多读少的情况下,即:需要频繁的写数据时候,可以考虑使用悲观锁。

(3)乐观锁和悲观锁实现方式

乐观锁实现方式

    乐观锁有两种实现方式: CAS机制 版本号机制

《1》CAS机制

CAS有三个操作数:

1) 需要读写的内存位置(V)
 2) 进行比较的预期值(A)
 3) 拟写入的新值(B)
    如果内存位置V的值等于预期的A值,则将该位置更新为新值B,否则不进行任何操作。 许多的CAS是自旋的,也就说如果一次不成功,它会一直循环去判断,直到成功为止。

自旋CAS就会占用系统资源,比较耗费CPU的开销。

CAS会导致ABA问题。

ABA问题是指: 线程1修改数据后值等于A,线程2修改数据后值变成B,线程2再次修改数据后值变成A,这样,CAS检查时候,发现修改前后的值是一样的,就认为没有修改,所以CAS操作成功。

《2》版本号机制

版本号机制,是在数据库中添加一个version字段,用于标识哪个版本。每当修改一次数据时候,会将版本号加1。
    当查询数据时候,将数据中的版本号一起查询出来。 接着修改数据,准备提交更新后的数据到数据库时候,再次查询数据库中版本号。 判断当前查询的版本号是否和第一次查询的一样,如果一样,则进行操作,否则重试。

悲观锁实现方式

    悲观锁实现,就是通过加锁。 可以对代码块加锁,也可以对数据加锁。 Java中可以使用synchronized同步代码块。 数据库中可以使用排它锁。
经验分享 程序员 微信小程序 职场和发展