【资料图】
在此之前,去看了下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的实现原理,不过在开发中,原本的代码...
花美人更美期待明年花再开!
截至2023年4月21日收盘,有研硅(688432)报收于18 7元,下跌9 0%,...
万万没想到,以文生图著名的Stable+Diffusion,也入局了大语言模型...
4月19日电,盈建科公布2023年一季度报告,报告期营业收入2242 61万...
中国教育和科研计算机网华南华中地区2023年学术会议在博鳌举办海南...
1 淡质虾米可摊在太阳下,待其干后,装入瓶内,保存起来。2 咸质...
雨生百谷,万物舒展。春日的大街小巷,人们品新茶、吃鲜饼、尝野菜...
【上市公司加码布局“银发经济”竞相角逐细分赛道】中国消费者协会4...
作者:谭媛要了解实际,就要掌握调查研究这个基本功。在调查研究中...
U I M F1摩托艇世界锦标赛,简称:F1H2O,是由国际摩托艇联合会...
中国江苏网讯纸是人们日常生活与学习中重要的伙伴之一,也是中华民...
欢迎观看本篇文章,小勉来为大家解答以上问题。英文版吻别歌词及翻...
NBA季后赛首轮G2,湖人客场93-103不敌灰熊,大比分被扳成1-1平。赛...
编者按:中华民族一家亲,石榴花开张家界。2023年,张家界市各族干...
46岁靳东满头白发身形佝偻,与荧幕形象判若两人,老得认不出来,伪装...
近期,有外媒报道称中国生产的无人机被出口到乌克兰战场,指责中国...
对于阿尔卡拉斯来说,巴塞罗那是一个非常特别的地方。他拥有出色的...
“您好,现在是学生放学高峰期,请您不要在公共场所吸烟……”4月13...
中新网4月19日电(中新财经彭婧如)“80后是保险消费的‘中流砥柱’,...
拼出来的胜利!记者:申花对阵泰山,跑动比对手多5000米,申花,吴曦,...
1、1990年,她和丈夫因为性格不合离婚了。2、当时,女儿考拉只有5个...
1、第一,搬家公司的选择。2、如果是简单的行李,自己搬是可以的。...
1、顿号_词语解释【拼音】:dùnhào【解释】:1 标点符号的一种,...
在山东省济南市槐荫区青年公园街道“如康家园”,每周都会有编织、...
1、四部作品分别代表了四位大师在各自的研究领域中,极具学术价值的...
点击蓝字关注我们透过数据看癌症科学防治有观点日常生活中应该如何...
4月17日上午,北京老字号协会副会长兼秘书长孙月婷、品牌促进专委会...
许多细心的朋友上厕所时会观察自己的排便情况,这有助于及时察觉身...
中国央行货币政策司司长邹澜20日在北京透露,据统计,截至今年3月末...