首页 > 其他分享 >悲观锁和乐观锁

悲观锁和乐观锁

时间:2024-03-26 12:01:49浏览次数:14  
标签:Synchronized CAS ReentrantLock 乐观 修改 线程 悲观 修饰

目录

悲观锁 通常用在多写场景

Synchronized

底层原理

修饰代码块,锁的是给定对象

修饰方法

ReentrantLock

Synchronized和ReentrantLock比较

乐观锁 通常用在多读场景

CAS的问题


悲观锁 通常用在多写场景

悲观锁假设总是最坏的情况,每次去访问公共资源时,都认为可能会出现问题,共享资源可能会被其他线程修改,所以每次访问公共资源的时候,对其进行加锁。其他线程想要访问该资源,就要被阻塞,一直到上一条线程执行完毕释放锁。

Synchronnized和ReentrantLock都是悲观锁的实现。

问题:高并发场景下,可能会造成大量的锁阻塞,并且还有死锁问题。

Synchronized

底层原理

本质都是获取锁监视器monitor的过程,默认是非公平锁。

修饰代码块,锁的是给定对象

monitorenter指令是获取锁,如果锁计数器是0,则表示可以获取锁,获取锁之后,锁计数器+1。获取锁失败就进入阻塞队列,等待下一次时间片的抢夺。

monitorexit指令是持有锁的线程释放锁的指令,释放锁之后,锁计数器-1,其他线程就可以获取锁了。

修饰方法

修饰实例方法,锁的是当前对象

修饰静态方法,锁的是当前类

使用ACC_SYNCHRONNIZED来标识一个是一个同步方法,

ReentrantLock

原理:基于AQS,是一个可重入且独占锁,默认是非公平锁,可以通过构造器显式指定公平锁。

相比Synchronized,ReentrantLock 更灵活、更强大,增加了轮询、超时、中断、公平锁和非公平锁等高级功能。

Synchronized和ReentrantLock比较

1、都是可重入锁(递归锁),否则会造成死锁问题。

2、synchronized是基于JVM,而ReentrantLock是基于Jdk的API。

3、ReentrantLock比Synchronized增加了很多高级功能

等待可中断、可实现公平锁、可选择性通知

乐观锁 通常用在多读场景

乐观锁假设总是最好的情况,每次访问资源都不会认为会出现问题,不会加锁也不会阻塞,可以一直运行。每次去修改时,需要校验对应资源有没有被修改过,如果有,则重新执行修改逻辑,如果没有,就提交修改。

CAS就是典型的乐观锁。

CAS的问题

问题:高并发场景下,如果写操作比较多的话,可能会造成频繁失败和重试,CPU压力过大。

CAS问题:ABA问题——CAS每次去修改值的之后,如果预期值A被其他线程修改为B,再修改为A,这个过程当前线程是不知道的。

解决方案:使用版本号机制或时间戳或标记字段都可以。

CAS问题:循环消耗大,失败重试直到成功。

解决方案:限制重试次数,一般限制为3次

标签:Synchronized,CAS,ReentrantLock,乐观,修改,线程,悲观,修饰
From: https://blog.csdn.net/weixin_45967584/article/details/137014353

相关文章

  • 多线程:乐观锁
     悲观锁:一上来就加锁,没有安全感。每次只能一个线程进入访问完毕后,再解锁。线程安全,性能较差!乐观锁:一开始不上锁,认为是没有问题的,大家一起跑,等要出现线程安全问题的时候才开始控制。线程安全,性能较好。为什么出现线程安全问题?100个线程每个加100次应该加10000次才对;因为......
  • MyBatisPlus 之四:MP 的乐观锁和逻辑删除、分组、排序、链式的实现步骤
    乐观锁乐观锁是相对悲观锁而言的,乐观锁假设数据一般情况不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果冲突,则返回给用户异常信息,让用户决定如何去做。乐观锁适用于读多写少的场景,这样可以提高程序的吞吐量。乐观锁采取了更加宽松的加......
  • 乐观锁与悲观锁
    乐观锁和悲观锁是处理数据库并发操作的两种不同策略乐观锁:乐观锁的核心思想是“乐观”,它假设在数据处理过程中,冲突发生的概率较低。因此,乐观锁不会在事务开始时就锁定数据,而是在数据提交时检查是否有其他事务修改过这些数据。如果数据未被修改,则事务可以成功提交;如果数据被其......
  • 乐观锁和悲观锁!!!
    概念乐观锁:乐观锁实在执行线程任务时,不会直接加锁,而是在数据记录中添加一个版本号。当事务需要更新数据时,它会检查版本号是否与之前读取时相同。如果相同,则执行更新操作;如果不同,则说明有其他事务在此期间修改了数据,当前事务需要重新执行读取和更新操作。悲观锁:悲观锁是在执行......
  • MySQL实战:解密乐观并发控制,确保数据操作不冲突
     概述:乐观并发控制是处理数据访问并发的一种策略,通过在更新前检查版本号或时间戳,确保数据在事务间保持一致性。在MySQL示例中,通过比对版本号,如果发现其他事务已更新数据,则拒绝当前事务的修改,避免潜在的并发冲突。这种机制提高了数据一致性,典型应用包括乐观锁的实现。数据访问......
  • 悲观锁和乐观锁
    最近面试都被问到这个,可是都只是靠着零散的记忆不知说了啥,那就好好整理一趟吧。悲观锁:当我们要对一个数据库中的一条数据进行修改的时候,为了避免同时被其他人需改,最好的方法就是直接对该数据进行加锁以防止并发。这种借助数据库锁机制在修改数据之前先锁定,再修改的方式称之为悲......
  • sqlserver 数据库事务ACID和使用 数据库锁,悲观锁乐观锁死锁
    在SQLServer中,事务的ACID属性、数据库锁、悲观锁、乐观锁和死锁是数据库管理和设计中的重要概念。以下是对这些概念的详细解释以及如何在SQLServer中使用它们:1.ACID属性在SQLServer中,事务必须满足ACID属性,以确保数据的一致性和可靠性。原子性(Atomicity):......
  • C#和sqlserver 如何实现 事务ACID和使用 数据库锁,悲观锁乐观锁死锁
    在C#中使用SQLServer实现事务的ACID(原子性、一致性、隔离性、持久性)属性和使用数据库锁(悲观锁和乐观锁)时,你可以通过ADO.NET的SqlConnection和SqlTransaction类来实现。下面是一些示例和概念说明。实现ACID事务ACID属性是事务处理的四个基本特征,它们确保事务在数据库中的正确......
  • MySQL乐观锁与悲观锁
    说明遇见并发情况,需要保证数据的准确性,也就是与正确的预期一致,此时就会用到锁。锁是在并发下控制程序的执行逻辑,以此来保证数据按照预期变动。如果不加锁,并发情况下的可能数据不一致的情况,这是个概率问题。乐观锁CAS简介乐观锁很乐观,假设数据一般情况不会造成冲突,属于程序层......
  • 使用悲观锁防止超卖问题
    记录一次使用悲观锁防止超卖的demo实例。环境配置可以参照我上篇笔记此处只展示核心代码 代码//先查库存Devicedevice=deviceMapper.selectByIdUpdate(3);//核心为该行代码//Thread.sleep(3000);if(device.getSortNum()>0){System.out.println("当前库存是:"+......