龙空技术网

乐观锁和悲观锁的区别?

CameSawConquer 106

前言:

现在姐妹们对“乐观和悲观锁的区别”都比较关注,各位老铁们都想要剖析一些“乐观和悲观锁的区别”的相关知识。那么小编在网上搜集了一些有关“乐观和悲观锁的区别””的相关内容,希望小伙伴们能喜欢,我们一起来了解一下吧!

乐观锁:指的是在操作数据的时候非常乐观,乐观地认为别人不会同时修改数据,因此乐观锁默认是不会上锁的,只有在执行更新的时候才会去判断在此期间别人是否修改了数据,如果别人修改了数据则放弃操作,否则执行操作。

冲突比较少的时候, 使用乐观锁(没有悲观锁那样耗时的开销) 由于乐观锁的不上锁特性,所以在性能方面要比悲观锁好,比较适合用在DB的读大于写的业务场景。

悲观锁:指的是在操作数据的时候比较悲观,悲观地认为别人一定会同时修改数据,因此悲观锁在操作数据时是直接把数据上锁,直到操作完成之后才会释放锁,在上锁期间其他人不能操作数据。

冲突比较多的时候, 使用悲观锁(没有乐观锁那么多次的尝试)对于每一次数据修改都要上锁,如果在DB读取需要比较大的情况下有线程在执行数据修改操作会导致读操作全部被挂载起来,等修改线程释放了锁才能读到数据,体验极差。所以比较适合用在DB写大于读的情况。

乐观锁的实现方式:

​ 乐观锁的实现方式主要有两种,一种是CAS(Compare and Swap,比较并交换)机制,一种是版本号机制。

CAS机制:

​ CAS操作包括了三个操作数,分别是需要读取的内存位置(V)、进行比较的预期值(A)和拟写入的新值(B),操作逻辑是,如果内存位置V的值等于预期值A,则将该位置更新为新值B,否则不进行操作。另外,许多CAS操作都是自旋的,意思就是,如果操作不成功,就会一直重试,直到操作成功为止。

​ 版本号机制:

​ 版本号机制的基本思路,是在数据中增加一个version字段用来表示该数据的版本号,每当数据被修改版本号就会加1。当某个线程查询数据的时候,会将该数据的版本号一起读取出来,之后在该线程需要更新该数据的时候,就将之前读取的版本号与当前版本号进行比较,如果一致,则执行操作,如果不一致,则放弃操作。

悲观锁的实现方式:

​ 悲观锁的实现方式也就是加锁,加锁既可以在代码层面(比如Java中的synchronized关键字),也可以在数据库层面(比如MySQL中的排他锁)

主要的应用场景:当要更新一条记录时,希望这条记录不被其他用户所修改,实现线程安全的更新。

实现步骤:

在表中添加version版本号的列在实体类中配置version的描述

乐观锁和悲观锁

标签: #乐观和悲观锁的区别 #悲观锁与乐观锁的现实用法 #悲观锁与乐观锁的现实用法是什么