乐观锁和悲观锁区别以及使用场景

乐观锁和悲观锁是并发控制中两种不同的策略,用于解决多个线程或进程同时访问和修改共享数据时可能出现的并发问题。

  1. 悲观锁

悲观锁的基本思想是,在数据被访问时,假设会有其他的线程或进程也会访问这个数据,所以在访问数据之前,先对数据进行加锁,确保只有当前的线程或进程可以访问和修改数据。悲观锁在执行操作之前总是获取锁,确保在修改数据的时候数据不会被其他的线程或进程修改,这种锁的机制会导致其他的线程或进程在访问该数据时会被阻塞。悲观锁在MySQL数据库中,通过使用SELECT ... FOR UPDATE或者SELECT ... LOCK IN SHARE MODE语句进行实现。在Java中,synchronized关键字和ReentrantLock类也是悲观锁的实现方式。

以下是一个使用悲观锁的示例Java代码片段,使用synchronized关键字来实现:

public synchronized void updateBalance(int accountId, double amount) {
    double balance = getBalance(accountId);
    balance += amount;
    setBalance(accountId, balance);
}
  1. 乐观锁

乐观锁的基本思想是,在数据被访问时,假设不会有其他的线程或进程也会访问这个数据,所以不对数据进行加锁。在执行修改操作之前,先读取数据的版本号或者时间戳等标识,将其与执行修改操作时的版本号或者时间戳进行比较,如果相同则表示可以执行修改操作,如果不同则表示数据已经被其他的线程或进程修改,当前的操作将失败,需要重新执行。乐观锁在MySQL数据库中,通过使用乐观锁机制的数据类型,如TIMESTAMP和ROWVERSION等来实现。在Java中,乐观锁的实现方式包括使用AtomicInteger和AtomicLong等原子变量,以及使用版本号机制等。

以下是一个使用乐观锁的示例Java代码片段,使用AtomicInteger类来实现:

private AtomicInteger balance = new AtomicInteger();

public void updateBalance(int accountId, double amount) {
    int oldBalance, newBalance;
    do {
        oldBalance = balance.get();
        newBalance = oldBalance + amount;
    } while (!balance.compareAndSet(oldBalance, newBalance));
}

以上是乐观锁和悲观锁的区别及其在Java语言和MySQL数据库中的示例说明。需要注意的是,乐观锁和悲观锁并非绝对的对立面,而是不同的策略,每种策略在不同的场景下有不同的适用性和优缺点

  1. 乐观锁和悲观锁的比较

乐观锁和悲观锁都有各自的优点和缺点,应根据实际应用场景和需求选择合适的锁机制。

乐观锁相对于悲观锁而言,具有以下优点:

  • 可以提高并发性能:乐观锁不需要等待锁,因此能够避免因等待锁而产生的阻塞和死锁问题,提高并发性能;

  • 适用性更广:乐观锁对读操作的性能影响比较小,适用于读多写少的场景;

  • 实现简单:乐观锁实现简单,代码量较少。

但是,乐观锁也存在以下缺点:

  • 可能产生冲突:由于乐观锁假设在数据被访问时不会有其他线程或进程对其进行修改,因此在多个线程或进程同时对同一个数据进行修改时,可能会产生冲突,导致某些操作失败,需要重新执行;

  • 实现难度较大:乐观锁需要额外的版本号或时间戳等标识,需要确保其正确性,实现难度相对较大。

悲观锁相对于乐观锁而言,具有以下优点:

  • 可以避免冲突:悲观锁在执行操作之前总是获取锁,确保在修改数据的时候数据不会被其他的线程或进程修改,避免了冲突问题;

  • 实现相对简单:悲观锁的实现相对简单,常用的数据库和编程语言都提供了对悲观锁的支持。

但是,悲观锁也存在以下缺点:

  • 性能较低:由于悲观锁需要等待锁,因此可能会产生阻塞和死锁问题,降低并发性能;

  • 适用性较窄:悲观锁对读操作的性能影响比较大,适用于读写操作相对平衡的场景。

综上所述,乐观锁和悲观锁各有优缺点,应根据实际应用场景和需求选择合适的锁机制。在实际应用中,也可以将两种锁机制结合使用,充分利用各自的优势,提高并发性能和数据访问的准确性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/16939.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

08 Kubernetes应用配置管理

课件 在 Kubernetes 中,secret 是一种用于存储敏感信息的对象。Kubernetes 支持以下三种类型的 secret: Opaque:这是默认的 secret 类型,可以用于存储任何类型的数据,包括字符串、二进制数据等。 Service Account&…

Python研究生组蓝桥杯(省二)参赛感受

为什么参加蓝桥杯? 今年是读研的第一年,看着我简历上的获奖经历“优秀学生干部”“优秀志愿者”“优秀毕业生”......大学四年,我竟然没有一次竞赛类的经历,也没有拿得出手的项目,我陷入了深深的焦虑。 听说蓝桥杯的…

[架构之路-183]-《软考-系统分析师》-13-系统设计 - 高内聚低耦合详解、图解以及技术手段

目录 第1章 什么是高内聚低耦合 1.1 概念 1.2 目的 1.3 什么时候需要进行高内聚低耦合 1.4 什么系统需要关注高内聚、低耦合 第2章 分类 2.1 内聚的分类 2.2 耦合的分类 第3章 增加高内聚降低耦合度的方法 3.1 增加高内聚 3.2 降低耦合度 第1章 什么是高内聚低耦…

超详细的R语言svykm函数绘制复杂抽样设计数据cox回归生存曲线(Kaplan-Meier)

我们在既往的文章《R语言绘制复杂抽样设计数据cox回归生存曲线(Kaplan-Meier)》中介绍了怎么使用jskm包的svykm函数绘制复杂抽样设计数据cox回归生存曲线(Kaplan-Meier),但是有粉丝觉得讲得不够详细,希望讲得详细一点,今天我们继续来介绍一下…

排序算法 — 归并排序

文章目录 归并排序介绍从下往上的归并排序从上往下的归并排序 归并排序实现从上往下的归并排序从下往上的归并排序 归并排序的时间复杂度和稳定性归并排序时间复杂度归并排序稳定性 代码实现核心&总结 每日一道算法,提高脑力。第五天(时隔7天,终于回…

Mybatis 框架 ( 一 ) 基本步骤

1.概念 1.1.什么是Mybatis框架 (1)Mybatis是一个半ORM(Object Relation Mapping 对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、…

【工具使用】- git实现gitee托管代码以及检出代码

1. 下载Git工具 git下载地址1:https://git-scm.com/download/win git下载2:https://mirrors.tuna.tsinghua.edu.cn/github-release/git-for-windows/git/Git%20for%20Windows%202.40.1/ 下载完成后安装 安装直接执行exe可执行程序,下一步…

Packet Tracer - 配置 RIPv2

Packet Tracer - 配置 RIPv2 目标 第 1 部分:配置 RIPv2 第 2 部分:验证配置 拓扑图 背景信息 尽管在现代网络中极少使用 RIP,但是作为了解基本网络路由的基础则十分有用。 在本活动中,您将使用适当的网络语句和被动接口配置…

【Java笔试强训 24】

🎉🎉🎉点进来你就是我的人了博主主页:🙈🙈🙈戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔🤺🤺🤺 目录 一、选择题 二、编程题 🔥年终奖 …

VC++ | MFC应用程序设计:框架搭建

VC | MFC应用程序设计:框架搭建 时间:2023-05-01 文章目录 VC | MFC应用程序设计:框架搭建1.启动程序2.新建项目2-1.新建项目2-2.应用程序类型2-3.文档模板属性2-4.用户界面功能2-5.高级功能选项2-6.生成的类2-7.解决方案资源管理器 3.工程文…

springboot websocket通信

目录 一、websocket是什么 二、实现websocket 2.1参考学习b站资料(一定要看,前后端详细) 2.2学习配套代码 一、websocket是什么 WebSocket_ohana!的博客-CSDN博客 二、实现websocket 2.1参考学习b站资料(一定要看…

Java 数组在内存中的结构是怎样的?数组访问、遍历、复制、扩容、缩容如何编写代码?

Java是一门面向对象的编程语言,数组是其中的重要数据结构之一。在Java中,数组是一种固定长度、有序的数据结构,可以存储一组相同数据类型的元素。在本文中,我们将详细介绍Java数组在内存中的结构。 Java数组的定义 在Java中&…

linux中使用docker部署微服务

目录 一、制作jar包(如果看一眼很简单,可以直接使用结尾的jar) 1.首先创建一个微服务 demo2 2.启动微服务(在DemoApplication上右键执行启动就行) 注意:其他操作导致的 可能遇到的报错 3.修改端口 4.新…

超细Redis(一)

目录 概述 Redis是什么? Redis能干嘛? 特性 如何学习 Linux安装 测试性能 概述 Redis是什么? Redis (Remote Dictionary Server),即远程字典服务 是一个开源使用ANSI C语言编写、支持网络、可基于内存亦可持…

【Java笔试强训 12】

🎉🎉🎉点进来你就是我的人了博主主页:🙈🙈🙈戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔🤺🤺🤺 目录 一、选择题 二、编程题 🔥二进制插…

Python小姿势 - Python学习笔记——类与对象

Python学习笔记——类与对象 类与对象是面向对象编程的两个基本概念。类是对象的抽象概念,对象是类的具体表现。 类是对一类事物的抽象,它是描述一类事物的模板,而对象是类的具体表现。对象是类的实例,类是对象的模板。 举个例子&…

STM32 系列 DAC的介绍与使用

STM32网上资料多,对自己来说基本的使用也是很简单的, 我的STM32专栏并没有什么系统的基础教学,基本上是某个项目用到了,或者产品使用过程出过问题 才会来记录一下,正好用到了 DAC ,一般产品还用得不多&…

QML应用动画(Applying Animations)

目录 一 扩展可点击图像元素版本2(ClickableImage Version2) 1 第一个火箭 2 第二个火箭 3 第三个火箭 动画可以通过以下几种方式来应用: 属性动画 - 在元素完整加载后自动运行; 属性动作 - 当属性值改变时自动运行&#xf…

【栈】的实现

🖊作者 : D. Star. 📘专栏 : 数据结构 😆今日分享 : —>📖区块链 : 小明向你借100块钱,说一周后还你,然后你拿个喇叭大喊一声:我是某某,小明向我借了100块&#xff0c…

Vue3+Element Plus环境搭建和一键切换明暗主题的配置

Vue (发音为 /vjuː/,类似 view) 是一款用于构建用户界面的 JavaScript 框架。而Element Plus是一款基于Vue3面向设计师和开发者的组件库。 最终效果: 环境搭建 已安装 16.0 或更高版本的 Node.js,终端: npm init vuelatest这一…
最新文章