针对RedisTemplate分布式锁实现WatchDog
2023-04-17 08:45:34 来源:腾讯云 小 中
(资料图片)
在此之前,去看了下Redission的实现原理,不过在开发中,原本的代码使用RedistTemplate实现的,也不太想换,所以我想了下,不如自己实现要给WatchDog。
我的想法是,在用户加上锁的时候开启个定时任务线程,并且在定时任务中,判断原线程isAlive状态进行“续命”。
下面是代码(在这里面为了方便,未使用的是HuTool.CornUtil来实现动态定时任务):
/** * Title * * @ClassName: LockUtil * @Description:锁工具类,通过内部枚举类实现单例,防止反射攻击 * @author: Karos * @date: 2023/1/4 0:17 * @Blog: https://www.wzl1.top/ */package cn.katool.lock;import cn.hutool.core.util.BooleanUtil;import cn.hutool.core.util.ObjectUtil;import cn.hutool.cron.CronUtil;import cn.hutool.cron.task.Task;import cn.katool.Config.LockConfig;import cn.katool.Exception.ErrorCode;import cn.katool.Exception.KaToolException;import cn.katool.other.MethodIntefaceUtil;import com.qiniu.util.StringUtils;import lombok.SneakyThrows;import lombok.extern.slf4j.Slf4j;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Scope;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.stereotype.Component;import org.springframework.util.ObjectUtils;import javax.annotation.Resource;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.TimeUnit;@Component@Scope("prototype")@Slf4jpublic class LockUtil { @Resource RedisTemplate redisTemplate; private LockUtil(){ } private static boolean isOpenCorn=false; /** * 带看门狗机制上锁 * @param lockObj * @return */ public boolean DistributedLock(Object lockObj){ try { return DistributedLock(lockObj,null,null); } catch (KaToolException e) { throw new RuntimeException(e); } } @Resource LockConfig lockConfig; //加锁 /** * 无看门狗机制上锁 * @param obj * @param exptime * @param timeUnit * @return * @throws KaToolException */ public boolean DistributedLock(Object obj,Long exptime,TimeUnit timeUnit) throws KaToolException { if (ObjectUtil.isEmpty(obj)){ throw new KaToolException(ErrorCode.PARAMS_ERROR," Lock=> 传入obj为空"); } Boolean isDelay=false; if (ObjectUtil.isAllEmpty(exptime,timeUnit)){ isDelay=true; } if(ObjectUtil.isEmpty(exptime)){ exptime= lockConfig.getInternalLockLeaseTime();; } if (ObjectUtils.isEmpty(timeUnit)){ timeUnit=lockConfig.getTimeUnit(); } //线程被锁住了,就一直等待 DistributedAssert(obj); Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent("Lock:"+obj.toString(), "1", exptime, timeUnit); log.info("katool=> LockUntil => DistributedLock:{} value:{} extime:{} timeUnit:{}",obj.toString(), "1", exptime, timeUnit); //实现看门狗 if (isDelay){ if (LockUtil.isOpenCorn==false){ //如果同一个项目之前打开过,那么先关闭,避免重复启动 CronUtil.stop(); //支持秒级别定时任务 CronUtil.setMatchSecond(true); //定时服务启动 CronUtil.start(); LockUtil.isOpenCorn=true; } Thread thread = Thread.currentThread(); TimeUnit finalTimeUnit = timeUnit; Long finalExptime = exptime; class TempClass{ public String scheduleId; } final TempClass tempClass = new TempClass(); tempClass.scheduleId=CronUtil.schedule("0/30 * * * * ?", new Task() { @SneakyThrows @Override public void execute() { boolean alive = thread.isAlive(); if (alive) { delayDistributedLock(obj, finalExptime>=3?(finalExptime / 3):finalExptime, finalTimeUnit); return; } else { if (tempClass.scheduleId==null||"".equals(tempClass.scheduleId)){ return; } CronUtil.remove(tempClass.scheduleId); DistributedUnLock(obj); return; } } }); } return BooleanUtil.isTrue(aBoolean); } //检锁 public void DistributedAssert(Object obj) throws KaToolException { if (ObjectUtils.isEmpty(obj)){ throw new KaToolException(ErrorCode.PARAMS_ERROR," Lock=> 传入obj为空"); } while(true){ Object o = redisTemplate.opsForValue().get("Lock:" + obj.toString()); if (ObjectUtils.isEmpty(o))return; } } //延期 public boolean delayDistributedLock(Object obj,Long exptime,TimeUnit timeUnit) throws KaToolException { if (ObjectUtils.isEmpty(obj)){ throw new KaToolException(ErrorCode.PARAMS_ERROR," Lock=> 传入obj为空"); } Boolean aBoolean = redisTemplate.opsForValue().setIfPresent("Lock:"+obj.toString(), "1", exptime, timeUnit); log.info("katool=> LockUntil => delayDistributedLock:{} value:{} extime:{} timeUnit:{}",obj.toString(), "1", exptime, timeUnit); return BooleanUtil.isTrue(aBoolean); } //释放锁 public boolean DistributedUnLock(Object obj) throws KaToolException { if (ObjectUtils.isEmpty(obj)){ throw new KaToolException(ErrorCode.PARAMS_ERROR," Lock=> 传入obj为空"); } Boolean aBoolean = redisTemplate.delete("Lock:" + obj.toString()); log.info("katool=> LockUntil => unDistributedLock:{} isdelete:{} ",obj.toString(),true); return BooleanUtil.isTrue(aBoolean); } //利用枚举类实现单例模式,枚举类属性为静态的 private enum SingletonFactory{ Singleton; LockUtil lockUtil; private SingletonFactory(){ lockUtil=new LockUtil(); } public LockUtil getInstance(){ return lockUtil; } } @Bean("LockUtil") public static LockUtil getInstance(){ return SingletonFactory.Singleton.lockUtil; }}
关键词:
相关文章
- 针对RedisTemplate分布式锁实现WatchDog
- 早知道:上市公司独立董事制度全面改革;宁德时代钠离子电池首发落地
- 广发证券:AI投资会有一段时间调整期,下一阶段依靠两方面外界因素_全球快资讯
- 环球动态:华泰证券:关注AI大模型在终端侧的轻量化应用
- 旺能环境:签署《监利市餐厨垃圾综合处理和资源化利用项目特许经营协议》|世界简讯
- 环球微头条丨中证报:因城施策持续显效,楼市企稳迹象渐增
- 证券日报:旅游市场加快复苏, “五一”出行热度高涨
- 中信建投:光伏估值处于低位 看好一季报业绩超预期方向_世界即时
- 冯柳192亿“豪赌”,顶流逃离_热点聚焦
- 全球新消息丨从明阳智能谈谈我的投资逻辑
- 所在城市龙头乳企降维打击已开始,其它乳企跟吗?|世界百事通
- 【天天时快讯】高瓴最新持仓;有牛市
- 今日快讯:但斌深夜发声回应言行不一:不干预旗下基金经理选择投资标的
- 多地聚焦“数商兴农” 政企合力助推乡村振兴
- 注册制改革全面落地首周:市场运行平稳,制度优势渐显
- 天天快消息!广发证券:AI投资会有一段时间调整期,下一阶段依靠两方面外界因素
- 国际油价攀高,国内成品油零售价将迎今年来最大涨幅|每日聚焦
- 天天热点评!商务部:正推动内地香港澳门共建单一自贸区
- 布局财富管理市场 保险机构瞄准基金销售牌照|全球报道
- 汽车智能化竞速赛开启 产业链加强合作
- 注册制改革全面落地首周:市场运行平稳,制度优势渐显
- 世界百事通!我自研兆瓦级PEM制氢装备性能进阶
- 多地聚焦“数商兴农” 政企合力助推乡村振兴
- 科研人员发现治疗非酒精性脂肪肝的潜在新药
- 经济日报:把促进高校毕业生就业放在突出位置,要稳定公共岗位规模-环球讯息
- 全球速看:埃安旗下首款纯电超跑Hyper GT开启预售
- 文旅局长“卷”上天 出游数据狂飙_全球报资讯
- 世界滚动:但斌再度高调力挺茅台
- 从年报透视A股公司“动力源”:研发大手笔,创新加速度|今热点
- 自由港、淡水河谷、英美资源等矿业巨头都在评估收购Teck Resources Ltd.基础金属业务的可能性
热文推荐
排行推荐

旺能环境:签署《监利市餐厨垃圾综合处理和资源化利用项目特许经营协议》|世界简讯
旺能环境(002034):签署《监利市餐厨垃圾综合处理和资... 更多>

环球微头条丨中证报:因城施策持续显效,楼市企稳迹象渐增
中指研究院认为,各地因城施策支持力度不断增强,短期... 更多>

证券日报:旅游市场加快复苏, “五一”出行热度高涨
携程旗下FlightAi市场洞察平台数据显示,截至4月14日... 更多>

中信建投:光伏估值处于低位 看好一季报业绩超预期方向_世界即时
中信建投最新研报表示,市场对于光伏板块预期悲观,主... 更多>
世界今日报丨俄罗斯总统普京会见李尚福
据新华社,当地时间4月16日,俄罗斯总统普京在莫斯科... 更多>
全球今热点:经济日报:确保电力平稳迎峰度夏
文章称,随着社会生产生活快速恢复,今年迎峰度夏期间... 更多>
经济日报:多渠道拓展国产大豆消费|全球滚动
国家粮食和物资储备局科学研究院首席研究员李爱科撰文... 更多>
天天热讯:国内成品油零售价将迎今年来最大涨幅,92号汽油每升上涨0.4元左右
受国际油价大幅攀升影响,国内汽柴油零售价结束连跌走... 更多>
【环球新视野】产业趋势投资中,如何赚“认知差”的钱?
投资进化论系列:消除不确定性这一轮令人瞠目结舌的AI... 更多>
全球观热点:写给所有散户的一封信:换手率大于7%意味着什么?看懂少走弯路!
所谓市场,就是交易场所。市场本身不产生利润。所谓赚... 更多>
上海谊众紫杉醇聚合物胶束新增适应症临床获批
$上海谊众(SH688091)$从国家药品监督管理局药品评审中... 更多>
机构开始覆盖光库_观点
光库周五涨13 69%。机构覆盖开始了。海通吹响号角,... 更多>
30年期国债期货即将上市 首批3个合约将于4月21日交易
具体而言,中金所在《通知》中称,30年期国债期货首批... 更多>
时讯:好奇和天真
$东阿阿胶(SZ000423)$自己的签名档从来到雪球就是这个... 更多>