zoukankan      html  css  js  c++  java
  • 悲观锁和乐观锁

    1:什么是悲观锁、乐观锁?

       生活里有两种人,悲观的,乐观的。悲观锁也就是对应悲观锁,把事情总是往坏处想。乐观锁也就是生活中乐观的人,把事情往乐观方面想。

    2:悲观锁

        悲观锁,总是把事情往坏处想。比如获取数据的时候,总担心别人修改自己要获取的数据。所以:悲观锁就是:共享资源每次只能给一个线程使用,其他线程阻塞,直到该线程使用完,才把资源让给其它线程。

       像 java 的 synchronized就是悲观锁

    3:乐观锁

         乐观锁,总是把事情往乐观处想,每次去拿数据都觉得别人不会修改,所以不会上锁,但是在更新的时候,会判断一下此期间有没有人去修改数据。可以使用版本号和CAS算法实现。乐观锁适用于读操作,这样可以提高吞吐量。

        想数据库提供的 write_condition机制,其实都是提供乐观锁。

       在  java.util.concurrent.atomic 包下的原子变量类就是使用乐观锁的一种CAS方式实现。

    4:乐观锁、悲观锁的使用场景?

        乐观锁适用于读的场景:提高吞吐量

        悲观锁适用于写的场景:减少retry,提高性能

    5:乐观锁的实现方式?

        1)版本号限制

             具体实现:在数据库加一个字段:version,每次读取+1,如果本地读取的值为2,在更新的时候为2,则可以更新,若不为2,则不允许更新。

        2)CAS算法

             compare and swap(比较和交换),是一种有名的无锁算法。即在不使用锁的情况下实现多线程之间的变量同步。

            CAS算法,涉及三个变量的操作:

             1):需要读取内存值:V

             2):进行比较的值:A

             3):拟写入的值:B

         当且仅当V的值和A的值相同,才允许使用原子的方式用新值:B替换掉V的值,否则什么也不做。一般情况下CAS是不断重试的。

    6:乐观锁的缺点?

       1):ABA问题。比如一开始读取的内存值V=A,当检查准备更新的时候发现还是A,那我CAS算法认为值没有被改动过,这是不对的。中间可能被改成B,之后再被改成A。JDK1.5解决了此问题:AtomicStampedReference 类提供了compareAndSet方法,检查当前引用是否等于预期引用,检查当前标志是否预期标志,如果全部都是预期的,则更新。

     

       2):循环开销大。自轩CAS算法在失败后会不断重试,如果一直失败,那么对于JVM来说是消耗巨大的。

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

    7:CAS和Synchronized使用场景?

         1)CAS:多读情况(冲突比较少)

         2)synchroized:多写情况(冲突场景较少)

      

  • 相关阅读:
    一个提高查找速度的小技巧
    COM是一个更好的C++
    15道简单算法题
    非递归实现文件夹遍历
    《STL系列》之map原理及实现
    《STL系列》之vector原理及实现
    MVC5 IIS7 403错误
    Vue在线客服系统【开源项目】
    Xcode No account for team "". Add a new account in the Accounts preference pane or verify that your accounts have valid credentials.
    CSS flex布局
  • 原文地址:https://www.cnblogs.com/qq1141100952com/p/13208196.html
Copyright © 2011-2022 走看看