zoukankan      html  css  js  c++  java
  • 并发编程--乐观锁与悲观锁

    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带来非常大的执行开销

  • 相关阅读:
    个人vim配置文件
    ORA-4031错误 解决方法
    HashMap在高并发下引起的死循环
    优先队列的应用
    java导入大量Excel时报错
    软件设计师必备——操作系统·
    Java Security安全系列文档翻译笔记————KeyStore、密钥、证书、命令行实战
    能变成有钱人的五个金玉良言(转)
    c3p0链接池
    js中获取键盘事件
  • 原文地址:https://www.cnblogs.com/Cryptonym/p/10675529.html
Copyright © 2011-2022 走看看