• 乐观锁和悲观锁区别


    什么是乐观锁,什么是悲观锁?

    乐观锁乐观锁在操作数据时非常乐观,认为别人不会同时修改数据。

    因此乐观锁不会上锁,只是在执行更新的时候判断一下在此期间别人是否修改了数据:如果别人修改了数据则放弃操作,否则执行操作。

    悲观锁悲观锁在操作数据时比较悲观,认为别人会同时修改数据。

    因此操作数据时直接把数据锁住,直到操作完成后才会释放锁;上锁期间其他人不能修改数据。

    两种锁的应该如何实现?

    乐观锁的实现方式主要有两种:CAS机制和版本号机制

    CAS:(Compare And Swap)

    CAS操作包括了3个操作数:

     1) 需要读写的内存位置(V)  2) 进行比较的预期值(A)  3) 拟写入的新值(B) 复制代码

    操作逻辑如下:

    如果内存位置V的值等于预期的A值,则将该位置更新为新值B,否则不进行任何操作。

    许多CAS的操作是自旋的:如果操作不成功,会一直重试,直到操作成功为止。

    这里引出一个新的问题,既然CAS包含了Compare和Swap两个操作,它又如何保证原子性呢?

    答案是:CAS是由CPU支持的原子操作,其原子性是在硬件层面进行保证的。

    注意:Java中的自增操作(i++)在并发场景下就不能百分百得到准确的结果,因为它并不是原子操作。

    在并发场景下应该使用AtomicInteger进行自增操作,其内部也是靠CAS乐观锁实现的顺序自增。

    版本号机制(Version)

    版本号机制的基本思路是在数据中增加一个字段version,表示该数据的版本号,每当数据被修改,版本号加1。

    当某个线程查询数据时,将该数据的版本号一起查出来;

    当该线程更新数据时,判断当前版本号与之前读取的版本号是否一致,如果一致才进行操作。

    需要注意的是,这里使用了版本号作为判断数据变化的标记,实际上可以根据实际情况选用其他能够标记数据版本的字段,如时间戳等。

    悲观锁的两种实现:synchronized和select...for update 代码实现悲观锁:synchronized synchronized通过对代码块加锁来保证线程安全:在同一时刻,只能有一个线程可以执行代码块中的代码。

    synchronized是一个重量级的操作,不仅是因为加锁需要消耗额外的资源,还因为线程状态的切换会涉及操作系统核心态和用户态的转换;

    不过随着JVM对锁进行的一系列优化(如自旋锁、轻量级锁、锁粗化等),synchronized的性能表现已经越来越好。

    sql实现悲观锁select...for update

    该查询语句会为该行记录加上排它锁,直到事务提交或回滚时才会释放排它锁;

    在此期间,如果其他事务只能对该行记录执行查询操作,如果更新该行记录信息或者执行select for update,会被阻塞。

    ps:用select for update一定要跟上where id = ? 的条件,id字段一定是主键或者唯一索引,不然会导致锁全表,后果很严重!

    分析一下两种锁的优劣势?

    乐观锁

    优势:

    轻量级锁,避免了线程切换的开销。

    劣势:

    会有ABA问题

    假设有两个线程——线程1和线程2,两个线程按照顺序进行以下操作

    (1)线程1读取内存中数据为A;

    (2)线程2将该数据修改为B;

    (3)线程2将该数据修改为A;

    (4)线程1对数据进行CAS操作

    在第(4)步中,由于内存中数据仍然为A,因此CAS操作成功,但实际上该数据已经被线程2修改过了。这就是ABA问题。

    只能对单一变量加锁

    自旋操作导致额外开销

    悲观锁

    优势:

    因为锁的是代码块,可以锁住多个变量。

    劣势:

    重量级锁,加锁、释放锁操作会有开销,而且操作系统层面的上下文切换和线程调度也会引起很大的开销。

    一个线程持有锁会导致其它所有需要此锁的线程挂起。

    不同场景如何选型乐观锁和悲观锁?

    高并发高竞争下,为了避免重试开销,直接选用悲观锁。

    比如火车票订票,在屏幕上显示有票,而真正进行出票时,需要重新确定一下这个数据没有被其他客户端修改。所以,在这个确认过程中,可以使用for update。

    并发情况不激烈,偶尔解决并发问题,选择性能消耗小的乐观锁。

  • 相关阅读:
    Pandas数据分析30——时间序列分析案例
    Nacos集群搭建
    Python数据分析--Numpy常用函数介绍(7)--Numpy中矩阵和通用函数
    如何治理 Electron 版本淘宝直播应用崩溃?
    携创教育:2023年4月自考考试时间首次公布!
    python学习(一) 列表,元组,字典,集合的区别
    HDL-Bits 刷题记录 04
    利用cmake工具生成VisualStudio工程文件
    FL Studio 21.2.3.4004 完整破解版 [Mac + Win] 下载 2024最新免费Crack 下载
    CV每日论文---2024.6.3
  • 原文地址:https://blog.csdn.net/luobotoutou123/article/details/128145730