• 并发编程--乐观锁与悲观锁


    1. 什么是乐观锁、悲观锁

    乐观锁:总是认为会是最好的情况,每次去取数据都认为别人不会修改,所以不会上锁,但是去更新的时候会判断在这期间有没有人对这个值进行修改,一般使用version机制CAS算法来实现;乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。

    悲观锁:总是认为会是最坏的情况,每次去取数据都认为别人会修改,所以每次取数据的时候都会上锁,别人取数据就会阻塞,直到它将这个锁释放掉,拿到锁才能取到数据;一般多写的场景下用悲观锁就比较合适,传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronizedReentrantLock等独占锁就是悲观锁思想的实现。

    2. 乐观锁的两种实现方式

    2.1 version版本号机制

    一般是在数据库表中加上一个版本号的字段version,该字段表示数据被修改的次数,数据每次进行修改时,都会进行version+1,当某个线程要更新数据时,会在读取数据的同时也读取到version值,然后提交更新时,会将获取到的version值与此时数据库中的值进行比较,如果相等进行更新,否则重试更新操作,直到更新成功

    2.2 CAS无锁算法

    即compare and swap(比较和交换),该算法主要涉及三个操作数:

    需要读写的内存值 V

    进行比较的值           A

    拟写入的新值      B

    只有当V=A时,通过原子的方式用B值更新V的值,否则不会进行任何操作。一般情况下是一个自旋操作,即不断的重试。

    3. 乐观锁的缺点

    1)ABA问题:如果线程1获取到变量的值为A,然后在线程1执行更新操作之前的这段时间里,线程2将这个变量的值先改成了B,然后又改回了A,此时线程1再去进行比较,会发现值是相等的,所以会认为在这期间该值没有被修改过.

    2)循环时间开销大:前面说过如果失败会一直重试更新操作,知道成功为止,如果一直不成功,会给CPU带来非常大的执行开销

  • 相关阅读:
    asp.net将图片转成二进制存入数据库
    ionic2打包生成APK报错 Error: Could not find gradle wrapper within Android SDK. Might need to update your Android SDK. Looked here: D:AndroidSDK ools emplatesgradlewrapper
    'ionic' 不是内部或外部命令,也不是可运行的程序或批处理文件。
    ABP-vs2017执行Add-Migration出现的问题
    关闭页面时,弹出JS提示框提示是否关闭
    C#生成Bar Code Image
    MemoryStream转imageSource
    RadControls RadGridView 显示加载数据时间
    RadGridView 分页控件
    CRM2011弹出asp.net模态窗口关闭的问题
  • 原文地址:https://www.cnblogs.com/Cryptonym/p/10675529.html
Copyright © 2020-2023  润新知