当前位置: 首页 > news >正文

PessimisticLock

想象你和你的朋友都想去图书馆借同一本非常受欢迎的小说。为了确保你们中的一位能够成功借到这本书,图书馆采用了悲观锁机制来管理借阅过程。

悲观锁的方式
  1. 查看书籍状态:当你到达图书馆并决定要借这本小说时,你先告诉图书管理员你想借这本书。此时,图书管理员会立即在系统中标记这本书为“正在处理”,这意味着其他任何人现在都不能再选择或预订这本书。
  2. 准备借书:接着,图书管理员开始为你办理借书手续,比如检查你的借书证、记录借阅信息等。在这段时间里,即使你的朋友也来到图书馆想要借同样的书,他们也会被告知这本书当前不可借用。
  3. 完成借书:一旦所有的手续都完成了,图书管理员会正式将书借给你,并更新系统的状态,表明这本书已经被借出。如果在这个过程中有任何问题导致无法完成借书,图书管理员会取消标记,并重新开放这本书的借阅权限。
  4. 释放资源:当你最终拿到书后,图书管理员解除对这本书的锁定,允许其他人再次尝试借阅它。

悲观锁的核心思想

  • 假设冲突经常发生:悲观锁认为并发修改是很常见的事情,因此它会在一开始就采取措施防止冲突的发生。
  • 提前锁定资源:当一个用户需要访问或修改某个资源时,悲观锁会立即将该资源锁定,阻止其他用户同时进行相同的操作。
  • 保持锁定直到操作完成:资源一直保持锁定状态,直到当前用户的操作完全结束,包括提交或回滚。
  • 阻塞其他请求:在资源被锁定期间,所有其他试图访问同一资源的请求都将被阻塞,必须等待当前操作完成。

Java中的悲观锁应用

在Java编程中,悲观锁通常通过显式地使用锁对象(如 ReentrantLock)或者数据库事务中的行级锁来实现。下面是一个简化示例,展示如何使用悲观锁控制对共享资源的访问:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class Book {private final Lock lock = new ReentrantLock();private boolean isAvailable = true;public void borrow() {// 获取锁,确保同一时间只有一个线程能执行以下代码块lock.lock();try {if (isAvailable) {System.out.println("成功借到了书!");isAvailable = false;} else {System.out.println("书已被借走,无法借阅。");}} finally {// 无论是否成功借书,最后都要释放锁lock.unlock();}}public void returnBook() {// 获取锁,确保同一时间只有一个线程能执行以下代码块lock.lock();try {if (!isAvailable) {System.out.println("书已归还!");isAvailable = true;} else {System.out.println("这本书已经可借了。");}} finally {// 无论是否成功归还书,最后都要释放锁lock.unlock();}}
}

        在这个例子中,borrow()returnBook() 方法都使用了 ReentrantLock 来实现悲观锁。当一个线程调用这些方法时,它会首先获取锁,然后执行相应的逻辑,最后确保总是释放锁。这样就保证了在同一时间点上,只有一个线程能够改变 Book 的状态,从而避免了并发冲突。

        悲观锁是一种保守的并发控制策略,它通过提前锁定资源来防止并发冲突。虽然这种方法可能会降低系统的并发性能,因为它可能导致其他请求被阻塞,但它提供了更强的数据一致性和安全性,特别适合那些写操作频繁且冲突可能性较高的场景。例如,在金融交易、库存管理和票务预订等领域,悲观锁可以帮助确保数据的准确性和完整性。

http://www.lryc.cn/news/511637.html

相关文章:

  • 【Maven】属性管理
  • 微信小程序性能优化、分包
  • TDengine 新功能 VARBINARY 数据类型
  • 【Maven】工程依赖下载失败错误解决
  • windows系统下使用cd命令切换到D盘的方法
  • 嵌入式小白
  • xilinx 芯片使用vivado导出pindelay文件——FPGA学习笔记24
  • 自研开发哪有什么捷径
  • 【Mac】终端改色-让用户名和主机名有颜色
  • ShenNiusModularity项目源码学习(6:访问控制)
  • STM32F103RCT6学习之三:串口
  • js 计算税率错误——如何处理
  • 12. 日常算法
  • HarmonyOS Next 实现登录注册页面(ARKTS) 并使用Springboot作为后端提供接口
  • 咖啡即将“从天而降”,无人机外卖时代来袭
  • kettle经验篇:Pentaho Repository 类型资源库卡顿问题
  • python opencv的sift特征检测(Scale-Invariant Feature Transform)
  • 若依定时任务
  • k8s-node2 NotReady 节点NotReady如何解决?
  • Ubuntu通过mDNS实现局域网local域名和octoprint域名访问
  • 短视频矩阵账号管理技术源码搭建详解,支持OEM
  • 【源码 导入教程 文档 讲解】基于springboot校园新闻管理系统源码和论文
  • Spark SQL DML语句
  • 开发微信小程序的过程与心得
  • 【1224】数据结构(sizeof/数组的长度定义/读取字符串函数/线性表长度/左值右值/静态变量/指针与引用)
  • Android笔记(四十一):TabLayout内的tab不滚动问题
  • 基于pytorch的深度学习基础3——模型创建与nn.Module
  • Debian-linux运维-docker安装和配置
  • Docker完整技术汇总
  • 在JavaScript文件中定义方法和数据(不是在对象里定以数据和方法,不要搞错了)