天天微动态丨针对RedisTemplate分布式锁实现WatchDog
(资料图片)
在此之前,去看了下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在此之前,去看了下Redission的实现原理,不过在开发中,原本的代码使用RedistTemplate实现的,也不太想换
-
百万巴萨库vs贝琉多拉_百万巴萨库_当前关注1、由德茹斯文明的自动防卫系统“巴萨库系统”发动,出现的机械兽(巴萨库)的最终形态。2、有麦克斯的几十
-
每日时讯!国内商品期市日间盘多数收跌 铁矿石跌超4%中国证券网讯4月21日日间盘,国内商品期货主力合约多数收跌。截至15:00,铁矿石跌超4%;沥青、焦煤、豆油、
-
孔新 世界新消息1、孔新,空军热血青春献礼剧《飞行少年》中的角色,由严屹宽扮演。2、。文章到此就分享结束,希望对大家有
-
今日快讯:手机电池充不进电的解救方法_手机电池充不进电1、专业鉴定:请按以下操作。2、故障原因:你的电池过放电了,电池启动了保护。3、过放电的电池在座充上显
-
精选!晚上做什么运动容易长高_做什么运动容易长高如果孩子还没有停止发育,坚持运动,加强营养,养成良好的生活习惯,可以促进他的成长。运动对身高增长有重
-
【环球新要闻】2023广州白云区消费券每天都有发放吗?2023广州白云区消费券每天都有发放吗?不是,活动期间每周五中午12:00开抢,限定位在广州市的用户可领取。
-
2023广交会第二期地址(附交通指南)|全球信息2023广交会第二期地址【展馆地址】地点:中国进出口商品交易会展馆A、B、C、D区(史上最大规模)地址:广州
-
富尔茨水货状元_水货状元今天小编肥嘟来为大家解答以上的问题。富尔茨水货状元,水货状元相信很多小伙伴还不知道,现在让我们一起来
-
成都养老保险缴费调标后前几月的缴费要补吗?怎么补? 当前通讯养老保险缴费调标后,当年前几月的缴费必须要补吗?怎么补呢?按照文件规定,企业职工基本养老保险缴费应以四
-
荣昌猪创意口号征集完成 今日18∶00开启线上投票_全球最资讯由荣昌区人民政府主办,荣昌区农业农村委(畜牧发展中心)承办,荣昌区融媒体中心、重庆琪金食品集团有限公
-
乐享集团(06988.HK):4月21日南向资金减持65.4万股4月21日北向资金减持65 4万股乐享集团(06988 HK)。近5个交易日中,获南向资金增持的有4天,累计净增持141
-
cf端游飞天挂软件下载_cf飞天外挂1、最好是上YY去下要不然别的都有毒。本文到此分享完毕,希望对大家有所帮助。
-
国务院安委会决定对北京长峰医院重大火灾事故查处实行挂牌督办 天天快播报4月18日,北京市丰台区北京长峰医院发生一起重大火灾事故,目前已造成29人死亡。国务院安委会决定,对该起
-
股票行情快报:华宝新能(301327)4月21日主力资金净买入5.82万元截至2023年4月21日收盘,华宝新能(301327)报收于143 48元,下跌0 7%,换手率3 54%,成交量8685 0手,成交额1 26亿元。
-
天天滚动:当日快讯:最高法:以居住为目的 全款购房的交付请求权,优先于建设工程价款优先受偿权 抵押权及其他债权4月21日,据人民法院报刊文,《最高人民法院关于商品房消费者权利保护问题的批复》已于2023年2月14日由最高
-
天天快讯:溢多利2022年净利1823.2万 董事长陈少美薪酬119.67万溢多利2022年净利1823 2万董事长陈少美薪酬119 67万2023 4 2121:48:30挖贝网蔡颖挖贝网4月21日,溢多利(300381
-
齐耳短发怎么扎好看_这款丸子头一定要尝试解答:1、首先,我们要准备一个发夹,一个发箍和一把梳子。然后,我们要做的就是梳头。这时候我们用梳子把
-
九强生物(300406):4月21日北向资金增持16.49万股 全球热消息4月21日北向资金增持16 49万股九强生物。近5个交易日中,获北向资金增持的有4天,累计净增持120 86万股。近
-
超声电子(000823):4月21日北向资金减持97.15万股 看热讯4月21日北向资金减持97 15万股超声电子。近5个交易日中,获北向资金减持的有3天,累计净减持109 28万股。近
-
欧元区4月综合PMI创11个月新高 但制造业PMI不及预期 焦点热议Markit指出,4月份的增长变得越来越不平衡:服务业报告了一年来最强劲的扩张,而制造业产出则以12月以来最
-
焦点观察:斯潘达姆_关于斯潘达姆简介1、斯潘达姆,日本漫画《航海王》及其衍生作品中的角色,世界政府直属秘密特务机关CP9长官,曾经担任CP5的
-
打造创新“引力场”!五大龙头企业即将齐聚柯桥纺博会 全球报资讯芳菲四月,百花争艳。踏着春天的脚步,2023中国绍兴柯桥国际纺织品面辅料博览会(春季)将于4月26-28日在绍
-
泌阳县人民检察院召开党组扩大会议 锚定目标 聚力攻坚 切实提升检察工作质效_天天报资讯Normal07 8磅02falsefalsefalseEN-USZH-CNX-NONE *StyleDefini
-
世界今日讯!券商今日看好的十大金股据证券之星统计数据,今日获得机构“买入”评级的十大金股。其中,启明星辰近一个月获得10份券商研报关注,
-
股票行情快报:汇创达(300909)4月21日主力资金净卖出462.84万元|全球微头条截至2023年4月21日收盘,汇创达(300909)报收于28 78元,下跌4 58%,换手率3 84%,成交量2 32万手,成交额6758 99万元。
-
今年一季度北京地区生产总值9947.7亿元 同比增长3.1%(记者陈杭)根据地区生产总值统一核算结果,今年一季度,北京市实现地区生产总值9947 7亿元,按不变价格计算
-
世界热门:iPhone 15 Pro Max独占:6倍光学变焦据MacRumors报道,iPhone15系列将推出四款机型,分别为iPhone15、iPhone15Plus、iPhone15Pro和iPhone15ProM
-
【新要闻】定额下浮合同范本(必备6篇)定额下浮合同范本第1篇发包人(全称):___承包人(全称):___根据《_合同法》、《_建筑法》及其他有关法律、
-
【独家焦点】俯瞰大片!跨海大桥高架路二期距离通车又近一步半岛全媒体记者王滨跨海大桥高架路一期西起胶州湾大桥李村河互通立交,沿李村河、张村河向东蜿蜒7 自2011年