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

  • 相关阅读:
    $Django 中间件 csrf
    $Django cookies与session--解决无连接无状态问题, session配置
    $Django Form组件
    $Django Paginator分页器 批量创建数据
    $Djangon admin界面 添加表 增删查改
    $Django ajax简介 ajax简单数据交互,上传文件(form-data格式数据),Json数据格式交互
    $Django 多对多-自定义第三张表 基于双下划线的跨表查询(补充)
    $Django 客户端->wsgi->中间组件->urls->views(model,template) 总结+补充(事物,choices,inclusion_tag)!
    $Django 聚合函数、分组查询、F,Q查询、orm字段以及参数
    经典的C++库【转帖】
  • 原文地址:https://www.cnblogs.com/Cryptonym/p/10675529.html
Copyright © 2011-2022 走看看