zoukankan      html  css  js  c++  java
  • 乐观锁和悲观锁的理解及如何实现,有哪些实现方式?

    悲观锁总是假设最坏的情况每次去拿数据的时候都认为别人会修改所以每 

    次在拿数据的时候都会上锁这样别人想拿这个数据就会阻塞直到它拿到锁 

    统的关系型数据库里边就用到了很多这种锁机制比如行锁表锁等读锁 

    锁等都是在做操作之前先上锁再比如 Java 里面的同步原语 synchronized  

    键字的实现也是悲观锁

    乐观锁顾名思义就是很乐观每次去拿数据的时候都认为别人不会修改 

    以不会上锁但是在更新的时候会判断一下在此期间别人有没有去更新这个数据

    可以使用版本号等机制乐观锁适用于多读的应用类型这样可以提高吞吐量

    像数据库提供的类似于 write_condition 机制其实都是提供的乐观锁 Java

     java.util.concurrent.atomic 包下面的原子变量类就是使用了乐观锁的一种实 

    现方式 CAS 实现的

    乐观锁的实现方式

    1、使用版本标识来确定读到的数据与提交时的数据是否一致提交后修改版本标 

    不一致时可以采取丢弃和再次尝试的策略

    2、java 中的 Compare and Swap  CAS ,当多个线程尝试使用 CAS 同时更新 

    同一个变量时只有其中一个线程能更新变量的值而其它线程都失败失败的 

    线程并不会被挂起而是被告知这次竞争中失败并可以再次尝试。 CAS 操作 

    中包含三个操作数 —— 需要读写的内存位置(V)、进行比较的预期原值(A)

    和拟写入的新值(B)。如果内存位置 V 的值与预期原值 A 相匹配那么处理器会自 

    动将该位置值更新为新值 B。否则处理器不做任何操作

    CAS 缺点

    1、ABA 问题

    比如说一个线程 one 从内存位置 V 中取出 A,这时候另一个线程 two 也从内存中 

    取出 A,并且 two 进行了一些操作变成了 B,然后 two 又将 V 位置的数据变成 A,

    这时候线程 one 进行 CAS 操作发现内存中仍然是 A,然后 one 操作成功尽管线 

     one  CAS 操作成功但可能存在潜藏的问题 Java1.5 开始 JDK  atomic

    包里提供了一个类 AtomicStampedReference 来解决 ABA 问题

     180   485 2、循环时间长开销大

    对于资源竞争严重线程冲突严重的情况,CAS 自旋的概率会比较大从而浪 

    费更多的 CPU 资源效率低于 synchronized。

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

    当对一个共享变量执行操作时我们可以使用循环 CAS 的方式来保证原子操作

    但是对多个共享变量操作时循环 CAS 就无法保证操作的原子性这个时候就可 

    以用锁

  • 相关阅读:
    LIB和DLL
    string
    Lists
    ctypes常用dll
    tomcat的安装配置注意事项
    tomcat6的简单安装
    存储GFS 学习笔记
    进程是否启动查看命令方法
    (转载)最新linux搭建gfs系统iscsi+GFS实现网络存储
    推荐两款支持在linux下运行ASP.NET网站的国产免费WEB服务器软件
  • 原文地址:https://www.cnblogs.com/programb/p/12771123.html
Copyright © 2011-2022 走看看