针对RedisTemplate分布式锁实现WatchDog 视点
在此之前,去看了下Redission的实现原理,不过在开发中,原本的代码使用RedistTemplate实现的,也不太想换,所以我想了下,不如自己实现要给Wat
(相关资料图)
在此之前,去看了下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; }} 标签:
在此之前,去看了下Redission的实现原理,不过在开发中,原本的代码使用RedistTemplate实现的,也不太想换,所以我想了下,不如自己实现要给Wat
当前,数字经济正为实体经济发展注入新动能,数实融合发展也成为当下各行各业最关注的趋势。游戏作为最具活力的数字内容形态之一,正在重构人
智通财经APP获悉,推特于4月20日开始结束之前的认证系统,改采用付费订阅制度,希望保留蓝证认证的用户必须每月8美元的费用订阅TwitterBlue服
近日,携程、飞猪等发布的报告均显示,距离“五一”假期不到10天,平台上的国内机票、酒店、景区门票等“五一”假期旅游产品的订单量均超过...
涡阳公司:“刷脸办电”开启用电服务新模式
这支球队,就是中国U22男足,今年9月份,他们就将踏上征程,出战U23亚洲杯的预选赛。然而还不等中国队的球员总结太多经验教训,新的比赛就已经
扭转下行态势,深入推进制造业高质量发展工业经济企稳向好势头足(经济新方位·首季数据观察)规模以上工业增加值同比增长3%,增幅高于去年四...
4月19日,记者来到位于栾城区的农林高科技园区,这里草木生机盎然,生长大棚内凉爽舒适,数名工人正在育苗,借助科技设施和预
由于薪资谈判陷入僵局,在德国服务业联合工会的呼吁下,德国杜塞尔多夫、汉堡和科隆-波恩三个机场的安保人员于当地时间20日和21日举行罢工,大
今天来聊聊关于5以内减法练习题可打印,5以内减法练习题的文章,现在就为大家来简单介绍下5以内减法练习题可打印,5以内减法
中央气象台:强冷空气将影响我国局地降温超12℃
风险提示及免责条款:市场有风险,投资需谨慎。本文不构成个人投资建议,也未考虑到个别用户特殊的投资目标、财务状况或需要。用户应考虑本文
周生生铂金多少钱一克(2023年04月21日)每日更新
4月20日,中熔电气(301031)融资买入371 63万元,融资偿还165 8万元,融资净买入205 83万元,融资余额5861 42万元,近20个交易日中有11个交易
4月20日上午,港股吉林长龙药业大涨超41%,一度涨超50%,创2016年以来新高。公司一季度归母溢利同比增长58%。
景点及旅游板块涨3 79%西域旅游涨10 39%居首
新华全媒+|肿瘤防治需警惕三大“夺命杀手”
交易商品牌 产地交货地最新报价SC原油 中质含硫原油,基准品质为API度32 0,硫含量1 5%SC原油上海国际能源交易中心上海市564 7元 桶
4月20日,国盾量子(688027)融资买入1092 48万元,融资偿还1732 08万元,融资净卖出639 6万元,融资余额2 35亿元。
狂飙25记三分!雄鹿追平季后赛单场三分纪录,一打热火就开挂,热火队,雄鹿队,nba,霍勒迪,阿德托昆博
近日,欧美同学会(中国留学人员联谊会)第三届“双创”大赛在湖南长沙启动。本届大赛分为报名、海选、初赛、产业决赛等阶段,并
你需要的东西集水盆抹布SAE20W-50机油CubCadet零转向系列割草机使您能够在短时间内切割大面积的草坪。与标准的骑乘式割草机相比,它们能够在更
1、中文名字:具银恩典 真实姓名:具恩宠 别名:hellokiki恩典恩宠KIKI 具恩宠(36张)韩
多地银行密集下调存款利率,释放什么信号?,央行,中小银行,定期存款利率
4月20日,中国高尔夫球巡回赛济南公开赛(以下简称“中巡赛济南公开赛”)新闻发布会在山东文旅崮云湖国际高尔夫球场(以下简
新华社北京4月19日电(记者高萌、许仕豪)19日是成都大运会开幕倒计时一百天,国务院新闻办公室举行新闻发布会,相关人士就
为切实加强春季防火期间的森林防灭火工作,预防森林火灾发生,敦化森林消防大队联合汪清县政府、应急管理局共同赴驻地屏风山森林公园、东明镇
1、有专业医师从解剖学角度讲解指出,最近微博疯传“性感臀窝”,其实这个结构术语叫做“骶凹”,其深面就是髂后上棘,两侧骶凹
隆鼻手术之后的恢复时间大概是在半个月左右,如果想要完全恢复的话,是需要三个月的时间恢复的,但由于每个人的身体状况不同,有些人恢复是比
据路透社报道,美国国防部19日公布了美俄军机在叙利亚上空近距离遭遇视频,称俄军机举动“不专业”。对于美方说法,俄方暂未回