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

    乐观锁和悲观锁

    1基本区别

    名称

    核心点

    说明

    场景

    悲观锁(pessimistic lock)

    操作之前加锁

    (最坏情况)

    每次拿数据时都认为别人会修改,因此每次拿数据时都上锁

    注意点:

    Mysql innodb中使用悲观锁一定要关闭自动提交属性(默认autocommit模式,即执行一个更新操作后,mysql会立刻将结果提交。)需要设置autocommit=0

    写多高并发

    关系型数据库行锁,表锁,读写锁等。

    JavasynchronizedReentrantLock等独占锁

    乐观锁(opitmistic lock)

    操作之前不加锁

    (最好情况)

    每次拿数据时认为别人不会修改,因此不上锁,更新时判断下数据有没有被更新

    读多低并发。

    版本号和cas方式实现。

    数据库提供的类似于write_condition机制。

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

    2乐观锁实现方式

    1)版本号

    update table set x=x+1, version=version+1 where id=#{id} and version=#{version};

    2)cas方式

    Compare and swap(比较与交换),无锁情况下实现多线程间变量同步。即非阻塞同步(non-blocking synchronization)

    实现操作数:

    需要读写的内存值V,进行比较的值A,拟写入的新值B

    当且仅当V值等于A时,CAS通过原子方式用新值B更新V的值,否则不会执行任何操作(比较和替换是一个原子操作),一般情况下是一个自旋操作(即不断重试)

    https://blog.csdn.net/hongchangfirst/article/details/26004335

    https://blog.csdn.net/liaohaojian/article/details/62416972

    https://blog.csdn.net/L_BestCoder/article/details/79298417

    https://blog.csdn.net/qq_34337272/article/details/81072874

    2.1乐观锁缺点

    问题

    说明

    解决方法

    ABA问题

    如果一个变量V初次读取时是A值,且在准备赋值时检查到仍然是A值,不能确定没有被其他线程修改过。因为可能被修改为其他值,然后又改回A值。即cas操作会误认为从来没有被修改过,即ABA问题。

    Jdk1.5后的AtomicStampedReference 类提供了compareAndSet。即先检查当前引用是否等于预期引用,并当前标志是否等于预期标志,如果全等,则以原子方式将该引用和标志值设置为给定的更新值。

    循环时间长开销大

    自旋CAS即不成功就一直循环执行直到成功,如果长时间不成功会增加cpu开销。

     

     

    2.2补充说明

    CASsynchronized使用场景:

     

    说明

    其他

    CAS

    低并发情况下,使用synchronized同步锁进行线程阻塞和唤醒切换额外浪费cpu资源。而cas基于硬件实现,不需要进入内核,切换线程,操作自旋几率少,性能更高

    注意:cas实现方式是使用cpu层面的命令保证原子性,硬件级别的!

    synchronized

    高并发情况下,线程冲突严重,cas自旋几率大,浪费过多cpu资源,效率低于synchronized

    Jdk1.6后对synchronized进行了优化

    https://blog.csdn.net/qq_34337272/article/details/81072874

    3悲观锁

    共享锁和排它锁是悲观锁的不同实现,一般数据库已实现,可直接调用。

    3.1Mysql中共享锁,排他锁,悲观锁,乐观锁

    3.1.1  innodbmyisam

    引擎

    说明

    其他

    innodb

    myisam最大不同点

    1)innodb支持事务

    2)Innodb采用行锁

    注意:行锁不是直接锁记录,而是锁索引。

    如果sql操作了主键索引则锁主键索引,操作非主键索引则先锁该非主键索引,再锁主键索引。如果没有索引或不通过索引条件检索数据,那么innodb将锁表。

    Mysql5.5之后使用innodb

    myisam

    Myisam操作数据使用表锁,性能低

    Mysql5.5之前默认使用myisam存储引擎

    3.1.2  mysql中锁

    注意:数据库增删改操作默认都会加排他锁,而查询不会加任何锁。

    数据库规定:同一资源上不能同时加共享锁和排他锁。

    类别

    说明

    场景

    共享锁

    对某一资源加共享锁,自身和其他人都可以读该资源,但无法修改。必须等所有共享锁释放完才能修改

    (读锁)

    多个不同事务对同一个资源共享同一个锁。(相当于一个门有多个钥匙)

    select * from myemployeee where id=322051 lock in share mode

    排他锁

    对某一资源加排他锁,自身可进行增删改查,其他人无法进行任何操作

    (写锁)

    select * from myemployeee where id=322051 for update

    https://blog.csdn.net/puhaiyang/article/details/72284702

    https://blog.csdn.net/localhost01/article/details/78720727

    mysql中的锁描述的还是不太清楚,后续再进行理解。

  • 相关阅读:
    java (java.exe) 解释器 -D 选项
    Ubuntu 12.04.3 X64 使用 NFS 作为文件共享存储方式 安装 Oracle11g RAC
    Ubuntu下 Oracle sqldeveloper中文目录、文件,select查询结果中:中文乱码
    行测题型
    Left join on where 区别
    常见公文——决定和请示
    宜家沙发测评
    "放管服"改革 清单
    shell && and ||
    ORA-01722: invalid number
  • 原文地址:https://www.cnblogs.com/cslj2013/p/10925850.html
Copyright © 2011-2022 走看看