乐观锁和悲观锁

╰+攻爆jí腚メ 2022-11-13 04:12 398阅读 0赞

这个问题经常在面试中被问到,在此做个记录!

一.乐观锁

​ 乐观锁就是总是认为事情总是朝着好的方向发展,总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在提交的时候会去判断一下在此之前有没有人改过这条数据。乐观锁主要通过版本控制和CAS算法实现。乐观锁适用于读比较多的场景,能获得比较好的吞吐量。

1.版本号机制:

​ 一般是在数据表中加上一个数据版本号version字段,表示数据被修改的次数,当数据被修改时,version值会加一。当线程A要更新数据值时,在读取数据的同时也会读取version值,在提交更新时,若刚才读取到的version值为当前数据库中的version值相等时才更新,否则重试更新操作,直到更新成功。

2.CAS算法

​ 即compare and swap(比较与交换),是一种有名的无锁算法。无锁编程,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻塞的情况下实现变量的同步,所以也叫非阻塞同步(Non-blocking Synchronization)。CAS算法涉及到三个操作数
需要读写的内存值 V
进行比较的值 A
拟写入的新值 B
当且仅当 V 的值等于 A时,CAS通过原子方式用新值B来更新V的值,否则不会执行任何操作(比较和替换是一个原子操作)。一般情况下是一个自旋操作,即不断的重试。

3.乐观锁的问题

1 ABA 问题
如果一个变量V初次读取的时候是A值,并且在准备赋值的时候检查到它仍然是A值,那我们就能说明它的值没有被其他线程修改过了吗?很明显是不能的,因为在这段时间它的值可能被改为其他值,然后又改回A,那CAS操作就会误认为它从来没有被修改过。这个问题被称为CAS操作的 “ABA”问题。
JDK 1.5 以后的 AtomicStampedReference 类就提供了此种能力,其中的 compareAndSet 方法就是首先检查当前引用是否等于预期引用,并且当前标志是否等于预期标志,如果全部相等,则以原子方式将该引用和该标志的值设置为给定的更新值。
2 循环时间长开销大
自旋CAS(也就是不成功就一直循环执行直到成功)如果长时间不成功,会给CPU带来非常大的执行开销。 如果JVM能支持处理器提供的pause指令那么效率会有一定的提升,pause指令有两个作用,第一它可以延迟流水线执行指令(de-pipeline),使CPU不会消耗过多的执行资源,延迟的时间取决于具体实现的版本,在一些处理器上延迟时间是零。第二它可以避免在退出循环的时候因内存顺序冲突(memory order violation)而引起CPU流水线被清空(CPU pipeline flush),从而提高CPU的执行效率。

二.悲观锁

所谓悲观锁,就是总是认为事情总是朝着不好的方向发展,总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以在拿数据的时候就加锁,这样别人想拿同个数据的时候就会阻塞。传统的关系型数据库很多就用到了这种锁机制,如:行锁、表锁、读锁和写锁等,都是在操作之前就加上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。悲观锁适用于写比较多的场景。

发表评论

表情:
评论列表 (有 0 条评论,398人围观)

还没有评论,来说两句吧...

相关阅读

    相关 悲观乐观

    悲观锁 即对一切数据修改持悲观态度,认为每次数据修改都会发生数据冲突,所以在一个线程对某一个数据进行读写操作后则直接为被读取的数据上锁,直至完成读写操作并更新数据;  

    相关 乐观悲观

    这个问题经常在面试中被问到,在此做个记录! 一.乐观锁 ​ 乐观锁就是总是认为事情总是朝着好的方向发展,总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不

    相关 乐观悲观

        乐观锁     乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制。悲观锁大多数情况下依靠数据库的锁机制实现,以

    相关 悲观乐观

    锁( locking ) 业务逻辑的实现过程中,往往需要保证数据访问的排他性。如在金融系统的日终结算 处理中,我们希望针对某个 cut-off 时间点的数据进行处理,而不希

    相关 乐观悲观

    乐观锁和悲观锁 数据库管理系统(DBMS)中的并发控制的是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和一致性以及统一性。 乐观并发控制(乐观锁)和悲观并

    相关 乐观悲观

    乐观锁和悲观锁主要用在数据库的并发访问控制上面 悲观锁:每次进行数据访问时都认为会发生冲突,因此屏蔽任何会影响数据完整性的操作。关系型数据库里边就用到了很多这种锁机制,比如行

    相关 悲观乐观

    1、悲观锁:    顾名思义,每次读取数据库的数据时,都假设会被它人修改,因此要加锁将数据锁住,防止被修改。   可以依靠数据库实现,如行锁、读锁和写锁等,都是在操作之前加

    相关 悲观乐观

    这是一篇介绍悲观锁和乐观锁的入门文章。旨在让那些不了解悲观锁和乐观锁的小白们弄清楚什么是悲观锁,什么是乐观锁。不同于其他文章,本文会配上相应的图解让大家更容易理解。通过该文,你