美文网首页
重温系列之多线程并发:乐观锁与悲观锁

重温系列之多线程并发:乐观锁与悲观锁

作者: 内卷星球 | 来源:发表于2019-03-31 10:43 被阅读0次

悲观锁:适合写操作多的场景,先加锁可以保证写操作时数据正确。
乐观锁:适合读操作多的场景,不加锁的特点能够使其读操作的性能大幅提升。

乐观锁

总是假设最好的情况,每次去拿数据的时候都认为不会修改,所以不会上锁,但在更新的时候会判断一下在此期间这个数据有没有更新,可以使用版本号机制和CAS(Compare And Swap)算法实现。
乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。

乐观锁一般会使用版本号机制或CAS算法实现。

实现方式

版本号机制

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

CAS算法

  • 需要读写的内存值 V
  • 进行比较的值 A
  • 要写入的新值 B

当且仅当 V 的值等于 A时,CAS通过原子方式用新值B来更新V的值,否则不会执行任何操作(比较和替换是一个原子操作)。一般情况下是一个自旋操作,即不断的重试。

乐观锁的缺点

  • ABA 问题

如果一个变量V初次读取的时候是A值,并且在准备赋值的时候检查到它仍然是A值,那我们就能说明它的值没有被其他线程修改过了吗?很明显是不能的,因为在这段时间它的值可能被改为其他值,然后又改回A,那CAS操作就会误认为它从来没有被修改过。这个问题被称为CAS操作的 “ABA”问题。
JDK 1.5 以后的 AtomicStampedReference 类就提供了此种能力,其中的 compareAndSet 方法就是首先检查当前引用是否等于预期引用,并且当前标志是否等于预期标志,如果全部相等,则以原子方式将该引用和该标志的值设置为给定的更新值

  • 循环时间长开销大

自旋CAS(也就是不成功就一直循环执行直到成功)如果长时间不成功,会给CPU带来非常大的执行开销

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

CAS 只对单个共享变量有效,当操作涉及跨多个共享变量时 CAS 无效。但是从 JDK 1.5开始,提供了AtomicReference类来保证引用对象之间的原子性,你可以把多个变量放在一个对象里来进行 CAS 操作.所以我们可以使用锁或者利用AtomicReference类把多个共享变量合并成一个共享变量来操作

悲观锁

总是假设最坏的情况,每次取数据时都认为其他线程会修改,所以都会加锁(读锁、写锁、行锁等),当其他线程想要访问数据时,都需要阻塞挂起。可以依靠数据库实现,如行锁、读锁和写锁等,都是在操作之前加锁,在Java中,synchronized的思想也是悲观锁。

补充

synchronized的底层实现主要依靠 Lock-Free 的队列,基本思路是 自旋后阻塞,竞争切换后继续竞争锁,稍微牺牲了公平性,但获得了高吞吐量。在线程冲突较少的情况下,可以获得和CAS类似的性能;而线程冲突严重的情况下,性能远高于CAS。

相关文章

  • 重温系列之多线程并发:乐观锁与悲观锁

    悲观锁:适合写操作多的场景,先加锁可以保证写操作时数据正确。乐观锁:适合读操作多的场景,不加锁的特点能够使其读操作...

  • 浅析乐观锁、悲观锁与CAS

    乐观锁与悲观锁 处理多线程并发访问最常用的就是加锁,锁又分成乐观锁和悲观锁。 悲观锁 在多线程访问共享资源时,同时...

  • Spring Elasticsearch data 乐观锁并发控

    Spring ElasticSearch data 乐观锁并发控制 乐观锁与悲观锁 悲观锁(Pessimistic...

  • 锁的概述

    乐观锁与悲观锁 悲观锁 乐观锁和悲观锁的概念出自数据库,但在java并发包中也引入和类似的概念(乐观锁/悲观锁是一...

  • ElasticSearch 7.x 实战入门06

    本节的主要内容:ES的乐观锁并发控制原理以及模拟过程 1、ES的乐观锁并发控制 1.1、悲观锁与乐观锁 悲观锁的优...

  • Java中的锁之乐观锁与悲观锁

    1、 分类一:乐观锁与悲观锁 a)悲观锁:认为其他线程会干扰本身线程操作,所以加锁 b)乐观锁:认为没有其他线程会...

  • 什么是CAS?

    一. 悲观锁与乐观锁 悲观锁: 假定会发生并发冲突,即共享资源会被某个线程更改。所以当某个线程获取共享资源时,会阻...

  • 乐观锁与悲观锁

    乐观并发控制(乐观锁)和悲观并发控制(悲观锁)是并发控制主要采用的技术手段 悲观并发控制(悲观锁) 它可以阻止一个...

  • mysql锁与事物隔离级别

    锁的定义 锁是计算机协调多个进程或线程并发访问某一资源的机制 锁分类 性能:乐观锁与悲观锁 操作:读锁和写锁(都属...

  • mysql锁(十)innodb下的悲观锁和乐观锁

    ****悲观锁与乐观锁****悲观锁,也叫悲观并发控制,当事务A对某行数据应用了锁,并且当这个事务把锁释放后,其他...

网友评论

      本文标题:重温系列之多线程并发:乐观锁与悲观锁

      本文链接:https://www.haomeiwen.com/subject/ijdybqtx.html