11 redis中分布式锁的实现

  1. 单机锁代码
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;public class AloneLock implements Lock {AtomicReference<Thread> owner = new AtomicReference<>();//队列--存放哪些没有抢到锁的线程LinkedBlockingQueue<Thread> waiters = new LinkedBlockingQueue<>();//实现加锁@Overridepublic void lock() {while (!owner.compareAndSet(null,Thread.currentThread())){waiters.add(Thread.currentThread());LockSupport.park();//让当前线程阻塞waiters.remove(Thread.currentThread());//解锁了,就需要把线程从等待列表中删除}}//实现解锁@Overridepublic void unlock() {if(owner.compareAndSet(Thread.currentThread(),null)){for (Object  object:waiters.toArray()){Thread  next= (Thread) object;LockSupport.unpark(next);}}}@Overridepublic void lockInterruptibly() throws InterruptedException {}@Overridepublic boolean tryLock() {return false;}@Overridepublic boolean tryLock(long time, TimeUnit unit) throws InterruptedException {return false;}@Overridepublic Condition newCondition() {return null;}
}
  1. redis分布式锁,之前的博客中也有其他的版本的,只是不支持本地重入方案。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.params.SetParams;import java.util.Arrays;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;/*** 分布式锁的实现*/
@Component
public class RedisDistLock implements Lock {private final static int LOCK_TIME = 5*1000;private final static String RS_DISTLOCK_NS = "tdln:";/*if redis.call('get',KEYS[1])==ARGV[1] thenreturn redis.call('del', KEYS[1])else return 0 end*///释放锁private final static String RELEASE_LOCK_LUA ="if redis.call('get',KEYS[1])==ARGV[1] then\n" +"        return redis.call('del', KEYS[1])\n" +"    else return 0 end";/*保存每个线程的独有的ID值*/private ThreadLocal<String> lockerId = new ThreadLocal<>();/*解决锁的重入*/private Thread ownerThread;private String lockName = "lock";@Autowiredprivate JedisPool jedisPool;public String getLockName() {return lockName;}public void setLockName(String lockName) {this.lockName = lockName;}public Thread getOwnerThread() {return ownerThread;}public void setOwnerThread(Thread ownerThread) {this.ownerThread = ownerThread;}@Overridepublic void lock() {while(!tryLock()){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}@Overridepublic void lockInterruptibly() throws InterruptedException {throw new UnsupportedOperationException("不支持可中断获取锁!");}@Overridepublic boolean tryLock() {Thread t = Thread.currentThread();if(ownerThread==t){/*说明本线程持有锁*/return true;}else if(ownerThread!=null){/*本进程里有其他线程持有分布式锁*/return false;}Jedis jedis = null;try {String id = UUID.randomUUID().toString();SetParams params = new SetParams();params.px(LOCK_TIME);params.nx();synchronized (this){/*线程们,本地抢锁,防止本地线程的不断重入*/if((ownerThread==null)&&"OK".equals(jedis.set(RS_DISTLOCK_NS+lockName,id,params))){lockerId.set(id);setOwnerThread(t);return true;}else{return false;}}} catch (Exception e) {throw new RuntimeException("分布式锁尝试加锁失败!");} finally {jedis.close();}}@Overridepublic boolean tryLock(long time, TimeUnit unit) throws InterruptedException {throw new UnsupportedOperationException("不支持等待尝试获取锁!");}@Overridepublic void unlock() {if(ownerThread!=Thread.currentThread()) {throw new RuntimeException("试图释放无所有权的锁!");}Jedis jedis = null;try {jedis = jedisPool.getResource();Long result = (Long)jedis.eval(RELEASE_LOCK_LUA,Arrays.asList(RS_DISTLOCK_NS+lockName),Arrays.asList(lockerId.get()));if(result.longValue()!=0L){System.out.println("Redis上的锁已释放!");}else{System.out.println("Redis上的锁释放失败!");}} catch (Exception e) {throw new RuntimeException("释放锁失败!",e);} finally {if(jedis!=null) jedis.close();lockerId.remove();setOwnerThread(null);System.out.println("本地锁所有权已释放!");}}@Overridepublic Condition newCondition() {throw new UnsupportedOperationException("不支持等待通知操作!");}}

问题:分布式锁的过期时间是不太好判断的,如何解决?
看门狗方案,实现自动续期,就是一个守护线程去判断过期时间。

实现方案:Redission插件

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

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

相关文章

前端国内镜像环境安装网址

git https://registry.npmmirror.com/binary.html?pathgit-for-windows/ 2.42.0 node 中文官方地址: http://nodejs.cn/download/ 阿里云镜像地址为: https://npm.taobao.org/mirrors/node/v14.6.0/

el-table 表格表头、单元格、滚动条样式修改

.2023.11.21今天我学习了如何对el-table表格样式进行修改&#xff0c;如图&#xff1a; 运用的两个样式主要是 1.header-cell-class-name&#xff08;设置表头&#xff09; 2.class-name&#xff08;设置行单元格&#xff09; 代码如下&#xff1a; <el-table :data&quo…

主播产品话术

以电子产品为例 一、产品特点 1.高效性能:这款产品采用了最先进的技术&#xff0c;确保高效运行&#xff0c;让你的工作更加流畅。 2.便捷操作:设计简洁&#xff0c;操作方便&#xff0c;即使是不熟悉电子产品的人也能轻松上手。 3.时尚外观:多种颜色可选&#xff0c;满足你…

springboot+bootstrap+java农业电商服务商城系统_30249

本农业电商服务系统是为了提高用户查阅信息的效率和管理人员管理信息的工作效率&#xff0c;可以快速存储大量数据&#xff0c;还有信息检索功能&#xff0c;这大大的满足了管理员、会员和商家这三者的需求。操作简单易懂&#xff0c;合理分析各个模块的功能&#xff0c;尽可能…

Cpolar - 本地 WebUI 账号登录失败解决方案

遇到这个问题是因为估计之前登录过其他账号导致的&#xff0c;那如何解决呢&#xff1f; 原因分析 因为之前历史账号登录过一次&#xff0c;本地配置信息里会残留&#xff0c;所以只要去除即可 解决方案 Windows 系统为例&#xff0c;MacOS 系统同理可得 找到 cpolar 配置文件…

【python学习】基础篇-常用模块-multiprocessing模块:多种进程间通信

multiprocessing模块提供了多种进程间通信方式&#xff0c;以下是一些常用的方法&#xff1a; 1、Queue: 创建一个队列对象&#xff0c;用于在进程之间传递数据。可以设置队列的最大长度和阻塞时间等选项。 from multiprocessing import Process, Queuedef worker(q):q.put(h…

实时云渲染 助力破解智慧园区痛点困局

智慧园区是运用先进的信息技术&#xff0c;如物联网&#xff08;IoT&#xff09;、大数据、云计算、人工智能、三维可视化等&#xff0c;对园区内的各类设施、资源以及管理进行智能化和数字化升级。其目标是通过科技手段提升园区的运营效率、资源利用率&#xff0c;提供更便捷、…

什么是软件需求?以及需求的最佳实践?

什么是软件需求 业务需求是反应企业组织对软件系统的高层次目标要求&#xff0c;换句话说就是软件系统的建设目标&#xff0c;常常体现在这两个方面&#xff1a;问题和机会。 要记住&#xff1a;出发点不同&#xff0c;精神面貌就完全不一样&#xff0c;当然如果目标过于夸大也…

机器人算法—ROS TF坐标变换

1.TF基本概念 &#xff08;1&#xff09;什么是TF&#xff1f; TF是Transformations Frames的缩写。在ROS中&#xff0c;是一个工具包&#xff0c;提供了坐标转换等方面的功能。 tf工具包&#xff0c;底层实现采用的是一种树状数据结构&#xff0c;根据时间缓冲并维护多个参考…

在AWS VPC中运行Nagios检查时指定自定义DNS解析器的选项

在AWS VPC中运行Nagios检查&#xff0c;并希望能够指定自定义DNS解析器来处理请求。我想使用Python requests库来实现这个目标。 根据问题描述&#xff0c;您想在AWS VPC中运行Nagios检查&#xff0c;并希望使用Python的requests库来指定自定义DNS解析器。 要解决这个问题&…

获取当前用户信息的几种方式

说明&#xff1a;在开发中&#xff0c;我们经常需要获取当前操作的用户信息&#xff0c;如创建用户、创建订单时&#xff0c;我们需要记录下创建人&#xff0c;本文介绍获取当前用户信息的三种方式。 方式一&#xff1a;使用ThreadLocal ThreadLocal本质上是一个Map&#xff…

一个c语言的hello world的本质是什么?

文章目录 hello world程序源文件的本质是0和1hello world文件的ASCII表示程序被其他程序翻译成不同的格式预处理阶段编译阶段汇编阶段链接阶段 为什么需要了解编译系统的工作原理&#xff1f;优化程序性能理解链接时出现的错误避免安全漏洞 参考 hello world 程序源文件的本质是…

IDEA版SSM入门到实战(Maven+MyBatis+Spring+SpringMVC) -Mybatis初识和框架搭建

第一章 初识Mybatis 1.1 框架概述 生活中“框架” 买房子笔记本电脑 程序中框架【代码半成品】 Mybatis框架&#xff1a;持久化层框架【dao层】SpringMVC框架&#xff1a;控制层框架【Servlet层】Spring框架&#xff1a;全能… 1.2 Mybatis简介 Mybatis是一个半自动化持久化…

银行业数据分析算法应用汇总

数据分析在银行业的应用及具体案例 一、欺诈检测二、客户细分三、风险建模四、营销优化五、信用评分六、客户流失预测七、推荐引擎八、客户生命周期价值预测 一、欺诈检测 欺诈检测即通过分析交易模式&#xff0c;检测可能的欺诈行为&#xff0c;主要有以下几个方面 1.跨机构开…

接口304 Not Modified

当客户端向服务端发送HTTP请求时&#xff0c;如果服务端返回状态码为304 Not Modified&#xff0c;则表明此次请求为条件请求。这意味着客户端已经缓存了该资源&#xff0c;并且该资源未被修改。在请求头中&#xff0c;客户端会发送两个请求参数&#xff1a;If-Modified-Since和…

Django 创建项目时找不到数据库sqlite3

原因:PyCharm创建Django项目,找不到数据库sqlite3 解决&#xff1a;如果没有默认的db文件&#xff0c;则应在PyCharm终端中执行以下命令&#xff1a; python manage.py makemigrations python manage.py migrate

文章解读与仿真程序复现思路——中国电机工程学报EI\CSCD\北大核心《就地无常规电源支撑下考虑新能源基地频率稳定的储能优化配置方法》

这个标题涉及到一个关于新能源基地频率稳定的储能优化配置方法的主题。让我们逐步解读&#xff1a; 就地无常规电源支撑下&#xff1a; 就地 (On-site): 意味着在特定地点或场地进行操作&#xff0c;而不是依赖外部地点的资源。无常规电源 (Non-conventional Power): 指的是不传…

python报错ModuleNotFoundError: No module named ‘docx‘解决方案

python报错ModuleNotFoundError: No module named docx解决方案 执行报错分析原因解决方案 执行报错 ModuleNotFoundError: No module named ‘docx’ pip install docx 后报错 分析原因 导错包了&#xff0c;不是docx而是python-docx 解决方案 卸载安装错的 docx pip uni…

足底筋膜炎症状及治疗方法

足底筋膜炎是一种常见的足部疾病&#xff0c;通常会引起足跟疼痛和不适。这种疼痛通常在早晨起床后或者长时间休息后更为明显&#xff0c;行走一段时间后可能会减轻。下面我们将详细介绍足底筋膜炎的症状及治疗方法。 一、足底筋膜炎的症状 足跟疼痛&#xff1a;这是足底筋膜…

2023/11/21JAVAweb学习

优先级高低id > 类 > 元素 格式化ctrl alt L