(资料图片)
在此之前,去看了下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实现的,也不太想换,所以我想了下,不如自己实现要给Wat
-
大数据分析软件有哪些软件_大数据分析软件有哪些
1、大数据分析用什么分析软件?一般基础数据分析用excel,origin,功能还是比较强大的,大数据分析用SAS,
-
王一博《长空之王》新预告:"威龙"歼-20硬核亮相!|全球最资讯
今日,王一博主演的五一档电影《长空之王》发布“威”版预告,“隐身外形,复合材料,超音速巡航”歼-20硬核亮相。
-
周五2只新股申购
经纬股份301390,价格37 70元 股;三博脑科301293,价格29 60元 股。
-
农业农村经济开局良好,夏粮丰收有基础,农民收入保持增长势头 各地深入挖掘农村内需潜力(权威发布)|天天信息
农业农村经济开局良好,为稳增长、稳就业、稳物价提供有力支撑。在4月20日举行的国新办新闻发布会上,农业农村部有关负责人介绍了一季度农业农
-
护士参加疫苗接种工作总结(推荐9篇)
护士参加疫苗接种工作总结第1篇关键词助产士职业暴露防护国外有研究显示,在最有职业危害的相关科室中,分娩室排在第2位。助产士因工作环
-
看热讯:【特刊】《黄山市创建“无梗城市”实施方案》解读
【特刊】《黄山市创建“无梗城市”实施方案》解读
-
西宁市总工会召开厂务公开民主管理标准化单位表彰会-环球微头条
西宁市总工会召开厂务公开民主管理标准化单位表彰会
-
当前消息!开平首个志愿服务组织孵化基地成立
环渤海新闻网消息(庄子孙陆杰)近日,开平区首个志愿服务组织孵化基地正式揭牌,国网唐山供电公司开平区越河供电所与河联一、二社区党群服务
-
需求萎靡,美联储加息或将延续,油价继续下跌|天天视点
【原油收盘】截至4月20日收盘:2023年5月WTI跌1 87报77 29美元 桶,跌幅2 36%,2023年6月布伦特跌2 02报81 10美元桶,跌幅2 4
-
美方指责中国电商平台有数据风险?商务部回应:中方严重关切 环球今日讯
App4月20日消息,今日,商务部举行例行新闻发布会。有记者提问:注意到近日美国国会下属的美中经济与安全审议委员会(USCC)发布分析师报告,
-
如何选择电视机?看这里就够了
虽然近些年各种手机、平板、电脑的飞速发展,让我们生活和娱乐有了更多的选择,但是依然有很多的家庭把电视机作为客厅C位的首选。电视机近些年
-
四大品牌一起上?奇瑞集团这次玩得大!_天天热点
四大品牌一起上?奇瑞集团这次玩得大!
-
全球实时:迪庆州:构筑绿色生态屏障
从迪庆藏族自治州香格里拉市出发,奔向虎跳峡镇,一路上景色如画。蜿蜒的高速公路犹如一条绸带飘在群山之间,金沙江两岸群山如黛
-
2021年最好听的名字男孩_好听寓意好的男孩名字 全球头条
欢迎观看本篇文章,小勉来为大家解答以上问题。2021年最好听的名字男孩,好听寓意好的男孩名字很多人还不知道,现在让我们一
-
焦点讯息:工信部:将全面推进电信服务线上办 异地办,精简套餐种类数量
据中国网,4月20日,国新办就2023年一季度工业和信息化发展情况举行发布会,会上,工业和信息化部总工程师、新闻发言人赵
-
达实智能:4月20日融资买入980.4万元,融资融券余额2.76亿元 快播
4月20日,达实智能(002421)融资买入980 4万元,融资偿还1258 8万元,融资净卖出278 4万元,融资余额2 73亿元,近20个交易日中有11个交易日出
-
环球热点评!综合实践课程设计要能帮助学生“学以致用”
“一碗喉吻润,两碗破孤闷,三碗搜枯肠,唯有文字五千卷……等诗人喝到第七碗时,已经两腋生风,欲乘清风到人间仙境蓬莱山上了。”“同学们,
-
当前信息:央行:M2增速与金融体系靠前发力等因素有关
阮健弘表示,3月末,M2余额是281 46万亿元,同比增长12 7%,比上月末低了0 2个百分点,比上年同期高3个百分点,M2增速保持在一个较高的水平上
-
天天看点:思科瑞:4月20日融资买入529.23万元,融资融券余额5427.43万元
4月20日,思科瑞(688053)融资买入529 23万元,融资偿还273 54万元,融资净买入255 69万元,融资余额4936 43万元,近20个交易日中有14个交易