news 2026/6/23 5:51:53

redis实现分布式锁

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
redis实现分布式锁

redis实现分布式锁

@ComponentpublicclassRedisDistributedLock{@AutowiredprivateRedisTemplate<String,String>redisTemplate;privatestaticfinalStringLOCK_PREFIX="lock:";privatestaticfinallongDEFAULT_EXPIRE=30_000;// 默认30秒// 加锁(带UUID防误删)publicStringtryLock(StringlockKey,longexpire){StringrequestId=UUID.randomUUID().toString();booleanresult=redisTemplate.opsForValue().setIfAbsent(LOCK_PREFIX+lockKey,requestId,expire,TimeUnit.MILLISECONDS);returnresult?requestId:null;}// 解锁(验证锁持有者身份后删除)publicbooleanunlock(StringlockKey,StringrequestId){Stringkey=LOCK_PREFIX+lockKey;StringcurrentRequestId=redisTemplate.opsForValue().get(key);if(requestId.equals(currentRequestId)){returnredisTemplate.delete(key);}returnfalse;}}

lua脚本实现方式

publicclassRedisDistributedLock{privateRedisTemplate<String,Object>redisTemplate;privateStringlockKey;privateStringlockValue;privateintexpireTime;// 获取锁的Lua脚本privatestaticfinalStringACQUIRE_LOCK_SCRIPT="if redis.call('setnx', KEYS[1], ARGV[1]) == 1 then "+"redis.call('expire', KEYS[1], tonumber(ARGV[2])) "+"return 1 "+"else "+"return 0 "+"end";// 释放锁的Lua脚本privatestaticfinalStringRELEASE_LOCK_SCRIPT="if redis.call('get', KEYS[1]) == ARGV[1] then "+"return redis.call('del', KEYS[1]) "+"else "+"return 0 "+"end";publicRedisDistributedLock(RedisTemplate<String,Object>redisTemplate,StringlockKey,intexpireTime){this.redisTemplate=redisTemplate;this.lockKey=lockKey;this.expireTime=expireTime;this.lockValue=UUID.randomUUID().toString();}/** * 尝试获取分布式锁 * @return 是否获取成功 */publicbooleantryLock(){RedisScript<Long>script=newDefaultRedisScript<>(ACQUIRE_LOCK_SCRIPT,Long.class);Longresult=redisTemplate.execute(script,Collections.singletonList(lockKey),lockValue,String.valueOf(expireTime));returnresult!=null&&result==1;}/** * 释放分布式锁 * @return 是否释放成功 */publicbooleanreleaseLock(){RedisScript<Long>script=newDefaultRedisScript<>(RELEASE_LOCK_SCRIPT,Long.class);Longresult=redisTemplate.execute(script,Collections.singletonList(lockKey),lockValue);returnresult!=null&&result==1;}/** * 带超时的获取锁方法 * @param timeout 超时时间(毫秒) * @return 是否获取成功 */publicbooleantryLock(longtimeout){longstartTime=System.currentTimeMillis();do{if(tryLock()){returntrue;}try{Thread.sleep(100);// 短暂休眠避免过度竞争}catch(InterruptedExceptione){Thread.currentThread().interrupt();returnfalse;}}while(System.currentTimeMillis()-startTime<timeout);returnfalse;}}

代码说明:

  1. 使用RedisTemplate的setIfAbsent方法实现原子加锁操作
  2. 通过UUID生成唯一请求ID,防止误删其他客户端的锁
  3. 解锁时通过Lua脚本验证锁持有者身份,确保原子性
  4. 支持自定义过期时间,防止死锁
  5. 依赖Spring框架,需配置RedisTemplate Bean
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/22 15:01:47

汇编:外设连接与中断

一、外设连接基础&#xff08;8086 体系&#xff09;1. 外设与 CPU 的连接方式CPU 通过地址总线、数据总线、控制总线与外设交互&#xff0c;核心方式有两种&#xff1a;端口映射&#xff08;I/O 映射&#xff09;&#xff1a;外设占用独立的 I/O 地址空间&#xff08;8086 为 …

作者头像 李华
网站建设 2026/6/23 5:27:22

为何要配光伏储能协调控制服务器?核心价值与应用必要性

在“双碳”目标与新型电力系统建设的双重驱动下&#xff0c;光伏储能&#xff08;以下简称“光储”&#xff09;一体化已成为新能源发展的主流模式。截至2024年三季度&#xff0c;全国光储一体化项目累计装机容量突破300GW&#xff0c;较去年同期增长68%。然而&#xff0c;不少…

作者头像 李华
网站建设 2026/6/22 22:51:03

优选算法-004 盛最多水的容器

题目链接&#xff1a;盛最多水的容器示例1&#xff1a;优选算法-004 方法1&#xff1a;暴力破解这个是最简单的方法&#xff0c;但是会超时把所有的情况都算一遍&#xff0c;不断更新最大面积&#xff0c;循环结束&#xff0c;保留的结果就是最大面积代码说明核心逻辑&#xff…

作者头像 李华
网站建设 2026/6/22 14:48:33

知识点总结

1.插入排序原理解释举个简单的例子&#xff1a;将10插入到已排序的数组arr中&#xff0c;保证数组元素从小到大排序int arr[10]{3,7,8,9,12,15};int key10;for(int i6-1;i>0&&arr[i]>key;i--){arr[i1]arr[i];}arr[i]key;将数组arr从后往前&#xff0c;从大到小遍…

作者头像 李华