悲观锁、乐观锁与分布式锁详解及Redisson应用

目录

  • 1. 悲观锁(Pessimistic Lock)
  • 2. 乐观锁(Optimistic Lock)
  • 3. Redis分布式锁
  • 4. Redisson锁

在多线程或多进程环境下,为了保证数据的一致性,锁机制扮演着至关重要的角色。本文将深入探讨悲观锁、乐观锁的概念,以及如何利用Redis实现分布式锁,并通过Redisson客户端展示具体的应用实例。最后,我们也会简要提及如何从Redis中删除缓存信息。

1. 悲观锁(Pessimistic Lock)

概念: 悲观锁假设最坏的情况,即每次数据操作都可能发生并发冲突,因此在数据被处理前就将其锁定,阻止其他线程访问,直到该线程完成操作并释放锁。这种方式适合写操作频繁的场景。
Java中的应用: 在Java中,synchronized关键字和ReentrantLock类可以用来实现悲观锁。

public class PessimisticLockExample {private final ReentrantLock lock = new ReentrantLock();public void doSomething() {lock.lock(); // 获取锁try {// 执行业务逻辑} finally {lock.unlock(); // 释放锁}}
}

2. 乐观锁(Optimistic Lock)

概念: 乐观锁则假设读多写少的情况,不直接加锁,而是在更新数据时检查在此期间数据是否被其他线程修改过。乐观锁常通过版本号或时间戳来实现,仅当数据实际需要更新时才进行冲突检查。
Java中的应用: 在数据库操作中,可以通过版本字段实现乐观锁。

@Entity
class User {@Versionprivate Long version;// 省略其他代码...
}// 更新用户信息时检查版本号
@Modifying
@Query("UPDATE User u SET u.name = ?1 WHERE u.id = ?2 AND u.version = ?3")
int updateUser(String newName, Long id, Long version);

3. Redis分布式锁

概念: 在分布式系统中,传统的锁机制无法跨越多个节点,因此需要分布式锁。Redis由于其高性能和易用性,常被用作分布式锁的实现基础。
基本用法:
SETNX (SET if Not eXists) 命令可以用来实现简单的分布式锁。
需要考虑锁的超时释放问题,使用 expire 命令设置锁的生存时间。

@RequiredArgsConstructor
public class RedisLock {private final String key;private final StringRedisTemplate redisTemplate;public boolean lock(long leaseTime, TimeUnit timeUnit) {String value = Thread.currentThread().getName();Boolean success = redisTemplate.opsForValue().setIfAbsent(key, value, leaseTime, timeUnit);return BooleanUtils.isTrue(success);}public void unlock() {redisTemplate.delete(key);}
}
        String key="lock:coupon:userId:"+userId;RedisLock redisLock = new RedisLock(key, redisTemplate);boolean locked = redisLock.lock(5, TimeUnit.SECONDS);if(!locked){throw new BadRequestException("请求太频繁");}try {// 获取用户优惠券服务IUserCouponService userCouponService = (IUserCouponService) AopContext.currentProxy();// 校验并创建用户优惠券userCouponService.checkAndCreateUserCoupon(coupon, userId, null);} finally {redisLock.unlock();}

4. Redisson锁

Redisson是Redis的Java客户端,它提供了丰富的并发工具,包括基于Redis的分布式锁、信号量、计数器等高级功能,简化了分布式环境下的并发控制。
Redisson分布式锁示例:

import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;public class RedissonDistributedLockExample {public static void main(String[] args) {Config config = new Config();config.useSingleServer().setAddress("redis://localhost:6379");RedissonClient redisson = Redisson.create(config);RLock lock = redisson.getLock("myLock");try {// 尝试获取锁,最多等待100秒,上锁后自动续期boolean isLocked = lock.tryLock(100, TimeUnit.SECONDS);if (isLocked) {// 执行业务逻辑} else {System.out.println("未能获取到锁");}} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {// 释放锁if (lock.isHeldByCurrentThread()) {lock.unlock();}}redisson.shutdown();}
}

通过上述介绍和示例,我们可以看到,悲观锁、乐观锁以及分布式锁(特别是通过Redisson实现)在不同场景下各有优势,选择合适的锁机制对于提升系统并发性能和数据一致性至关重要。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Python进行数据分析

哈喽,大家好,我是木头左! 14.1 Python在数据分析中的优势 Python作为一种简单易学、功能强大的编程语言,已经成为了数据分析领域的首选工具。它的优势主要体现在以下几个方面: 简洁高效:Python语法简洁明了,易于阅读和编写,能够快速实现复杂的数据分析任务。丰富的库支…

Python基于逻辑回归分类模型、决策树分类模型、LightGBM分类模型和XGBoost分类模型实现车辆贷款违约预测项目实战

说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 随着经济的发展和人民生活水平的提高,汽车消费在居民消费中所占比例逐渐增加,汽…

克服指标管理痛点,实现数据价值最大化

在当下的企业管理中,由于数据量的激增,管理方式逐渐从基于经验转向基于数据。在此过程中,我们能够通过数据探查业务情况、分析数据,从而获取更优的决策支持数据。这通常通过数据报表或分析平台来实现,对于临时性场景&a…

vue2组件内部获取路由前后变化

问题: 在账户列表页面,需要检测路由变化进行拉取用户数据,不在mounted里面写,就是要检测路由变化并且要获取前后路由的路径,进行一些逻辑的判断 解决: export default {data() {return {user: "&qu…

Feign调用异常

TimeLimiter SuperCareAPI#originalWave(String,String) recorded a timeout exception. 解决方案: 针对超时的接口设置响应时间 feign:client:config:default:connect-timeout: 500000000read-timeout: 500000000 resilience4j:timelimiter:instances:SuperCare…

护眼大路灯哪个牌子好用?五款好用的护眼灯分享

护眼大路灯哪个牌子好用?现在的孩子从幼儿园开始就开始学习,面临的用眼压力就很大,但想要孩子视力不受影响,大路灯是得好好安排起来,但动辄大几千的护眼灯真是让我们这些普通家庭的家长望而却步,有没有好用…

ruoyi-cloud部署过程遇到的问题总结

nacos启动失败 1.集群cluster模式改为单机standalone 修改bin/startup.cmd文件 set MODE"cluster" 改为 set MODE"standalone" 2.密钥长度不够“the length of secret key must great than or equal 32 bytes; ” 转到官网查看一些配置,发现…

控制系统稳定性常见策略

提升控制系统稳定性是确保系统可靠运行的关键,以下是一些常见策略: 1. 控制算法优化 优化控制算法是提升系统稳定性的核心方法之一。常见的控制算法包括PID控制、模糊控制、自适应控制等。通过调整和优化这些算法的参数,可以显著提高系统的…

FITC-链霉亲和素在生物成像技术中的应用

生物成像技术是现代生物学和医学研究中的工具之一,它使得研究者能够直观地观察和了解生物体内部的结构和功能。其中,荧光成像技术因其高灵敏度和高分辨率而受应用。FITC-链霉亲和素作为一种荧光标记试剂,在生物成像技术中发挥着作用。 FITC-…

Java List操作详解及常用方法

Java List操作详解及常用方法 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 什么是Java List? Java中的List是一种动态数组,它允许存…

填报高考志愿时,学校、专业和城市怎么选择呢?

我的观点是: 专业>城市>学校 专业是兴趣导向,符合自己的价值观,失去了这种驱动力的专业学习,会变得非常艰难的,而且没有竞争力,所以我的排序第一位是专业。 其次是城市,最好是一线城市&…

ubuntu22.04下编译安装dlib

为什么要自己编译,请自行摆渡。 #--------------------------------------------------------------------------- # compile and inistall dlib C library #--------------------------------------------------------------------------- cd /opt mkdir dlib-ro…

垃圾回收算法和 GC Roots 的对象

判断对象是否要回收有两种算法, 引用计数法和可达性算法。无论哪种都离不开引用,下面将介绍 Java 语言的四种引用。 众所周知,Java 语言的 JVM 垃圾回收机制,用可达性分析算法来判断堆里的对象是否正在使用。 可达性分析算法是从 GC ROOTS 开…

划重点!炒伦敦金看k线图的要点

对于刚刚开始参与伦敦金交易,还在学习如何看K线的投资者来说,掌握一些看k线图的要点,对于更好地分析市场的行情走势,找到有利的入场机很有帮助,以下是一些关键的建议,希望能够供大家参考。 K线有阳线和阴线…

区块链不可能三角

区块链不可能三角:探索去中心化、安全与可扩展性的权衡 引言 区块链技术自诞生以来,以其去中心化、透明、安全等特点吸引了全球的关注,成为金融科技领域的重要革新力量。然而,随着区块链应用的日益广泛,一个核心问题…

Coze搭建《测测你的本命宠物》

前言 本文讲解如何从零开始,使用扣子平台去搭建《测测你的本命宠物》 《测测你的本命宠物》:测测你的本命宠物 - 扣子 AI Bot (coze.cn) 欢迎大家去体验一下!!! 正文 接下来我们开始讲解制作这个bot的流程吧&#…

微信小程序常用的事件

1.点击事件 WXML 中绑定点击事件&#xff1a; <!-- index.wxml --> <button bindtap"handleTap">点击我</button> 对应的 JS 文件中编写点击事件处理函数&#xff1a; // index.js Page({handleTap: function() {console.log(按钮被点击了);} }…

【python入门】数组、元组、字典

文章目录 数组&#xff08;List&#xff09;元组&#xff08;Tuple&#xff09;字典&#xff08;Dictionary&#xff09; Python 是一种非常灵活的编程语言&#xff0c;它提供了多种数据结构来存储和操作数据。下面是 Python 中数组、元组和字典的详细说明&#xff0c;以及一些…

rclone 上传资料到 onedrive 遇到限速问题解决

原因分析 可能和脚本参数设置有关系,我的参数是: rclone copy "F:\阿里云盘\6666\局域网" "od:影视" --ignore-existing -u -v -P --transfers20 --ignore-errors --buffer-size128M --check-first --checkers10 --drive-acknowledge-abuse差不多8G大小的…

图像直方图的计算

1.1 cv.calcHist()函数&#xff0c;函数原型如下&#xff1a; void cv::calcHist ( const Mat * images,int nimages,const int * channels,InputArray mask,OutputArray hist,int dims,const int * histSize,const float ** ranges,bool uniform true,bool accumu…