• 悲观锁和乐观锁


    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:多写情况(冲突场景较少)

      

  • 相关阅读:
    HTML5 新增元素梳理
    HTML布局梳理
    ES6中新增let命令使用方法
    xml学习-语法规则
    初步了解URL
    JavaScript——装饰者模式
    移动视频技术——新增API可手工修正视频方向
    如何在移动视频开发中使用ip组播技术
    Windows平台AnyChat视频显示
    如何实现音频合成立体声录制?
  • 原文地址:https://www.cnblogs.com/qq1141100952com/p/13208196.html
Copyright © 2020-2023  润新知