您的位置:首页 >资讯 > 热点 >

针对RedisTemplate分布式锁实现WatchDog|微头条

2023-04-21 16:08:56    来源:腾讯云


(相关资料图)

在此之前,去看了下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;        }}

相关阅读

精彩放送

全球即时:周口市太康县委政法委召开风险隐患排查推进会

当前要闻:交上安保“满分卷” 官渡公安为高等教育自学考试护航

奢侈品售后扶不起

世界今日报丨绿通科技董秘回复:根据中国登记结算公司主动下发的数据,截至2023年4月20日

剪纸描绘昌平故事,传统文化韵味悠长

热资讯!刚刚,央行重磅发声!信息量巨大!

2023吉祥文化金银币价格表(2023年04月21日)

广立微:4月20日融资买入2842.78万元,融资融券余额1.74亿元

资讯推荐:北京2023二建准考证在哪里打印

新资讯:空调管子怎么巧妙装饰

每日看点!发改委:及时开展中央猪肉储备调节工作 促进生猪市场平稳运行

关注:内蒙古今年首趟旅游专列开行

世界实时:雷克萨斯豪华MPV全新一代LM全球首发

环球新动态:抵押贷款对征信有影响吗?有影响,但仍可应对

“购、游、食、赛、展” 2023闵行购物节4月28日开幕

天天报道:【新时代新征程新伟业——坚定不移推动高质量发展】闻喜桐城镇:为中小企业发展...

观天下!酒祖杜康·癸卯年黄帝故里拜祖大典供奉用酒灌装仪式圆满礼成

天天实时:让孩子发挥想象力和动手能力!迎暄社区开展风筝DIY手绘活动

三井住友金融集团发行1400亿日元AT1债券

全球热推荐:全球精炼锌供需格局转变,中期锌价仍有下行压力

焦点关注:Prada是哪个国家的品牌(Prada包包如何清洗)

当前简讯:英国公司研发磁场充电新技术,电动汽车充电10分钟可行驶320公里

热消息:内蒙古高校本科专业新增38个 20个专业弥补重点产业链相关领域布点空白

当前观点:环球漫评|“五个一百”:从时代脉搏中读懂美丽中国

今日要闻!洛阳钼业:投建的刚果(金)TFM铜钴矿混合矿项目已完成基建剥离与土建施工任务

2023中国生物材料大会征文通知

上海健麾信息技术股份有限公司 关于参与投资私募基金的进展公告

天天热文:东吴沪深300指数型证券投资基金暂停申购(含定期定额)业务的公告

每日速递:Python基础语法-函数-生成器函数

当前讯息:苹果密码忘了怎样恢复出厂设置_苹果密码忘了怎么恢复出厂设置

【环球热闻】如何选购淡水鱼 怎样挑选品质好的淡水鱼呢

【天天聚看点】瑞金医院开启晚期胰腺癌细胞治疗临床试验,开辟治疗新路径

热资讯!交大昂立:公司股东提起股东代表诉讼

每日快报!陕西气象部门连发预警 4月下旬再现大降温异常吗?

消费电子板块4月18日涨1%,美格智能领涨,主力资金净流出12.56亿元

世界即时看!第六届届数字中国建设峰会怎么参加

全球即时:俄罗斯战略轰炸机升空,日本紧张应对

每日热门:“中国光谷”政银联动 破解中小企业“首贷难”

世界速读:血赎 第一卷 乱世再起 第八十三章 战(2)

码表260是什么档次的车_码表

南京玄武:“红领店长”激发街区发展新动能

环球速读:降价无望?董事称宝马对价格战没兴趣 将全力电动化

天天热讯:公积金提取方法 介绍基本条件及办理流程

天天快消息!龙宇股份发生2笔大宗交易 合计成交1860.00万元

腾龙股份大宗交易成交976.00万股 成交额6880.80万元

工商银行信用卡账单日怎么查询 所有查看方法整理好了

速递!国货化妆品牌风潮袭来

环球看热讯:最新互联网保险消费者洞察报告发布 哪些趋势值得关注?

世界即时:艾瑞咨询:横向折叠屏是未来主要升级方向,国产品牌开足马力冲

天天通讯!3·15闪耀我守护我丨45天速成瑜伽教练?贷款购课培训,课没上完机构失联了

每日资讯:最新!坠亡杂技女演员家属获公司赔偿,其遗体已送回老家

世界今热点:青岛至悉尼航线4月23日起复航

看热讯:注意!双林股份将于5月9日召开股东大会

海外华媒走进四川宜宾 探寻“千年酒都”转型“新动力”

ChatGPT 标注指南来了!数据是关键

环境保护主管部门实施查封、扣押办法_关于环境保护主管部门实施查封、扣押办法介绍

环球通讯!阳光保险:财险业务盈利强劲,风险减量服务展现客户思维

世界今日报丨浙师大法政学院李老师 浙师大法政学院

环球通讯!中汽协:一季度汽车制造业固定资产投资同比增长19.0%

环球简讯:卡拉瓦乔艺术漆作为艺术漆十大品牌,品质 服务 口碑是赢得市场的关键

中航电子:截至2023年4月10日,公司股东总户数为9.13万户

天天快看点丨乐平市气象台更新暴雨黄色预警信号【III级/较重】【2023-04-18】

贵州省委办公厅、省政府办公厅印发《贵州省乡村建设行动实施方案(2023—2025年)》

环球观天下!《金瓶梅》最露骨的八句话,说尽人心,识透人性

世界速递!防弹少年团田柾国将 solo 出道 赴美国约见名制作人

天天快看:民航局:一季度全行业共完成旅客运输量1.29亿人次 同比增长68.9%

源飞宠物(001222)4月18日主力资金净买入386.54万元

环球滚动:发布越野混动架构,坦克品牌发力新能源市场

达州宣汉:社区爱心志愿服务队 暖了百姓心窝窝

【全球报资讯】租赁圆桌快讯 | 章林:住房租赁行业差异化特色并没有形成

环球即时:壶口景区人气渐旺

快讯:青岛西海岸新区红石崖街道:多措并举,优化企业营商环境

环球今日报丨天赐材料回应一季报业绩下滑:低端产能面临出清,市占率有望再次提升

华为nova 11系列发布!易烊千玺现场分享产品体验

4月17日基金净值:财通价值动量混合最新净值4.137,跌1.52%

求应届毕业生面试时自我介绍范文怎么写_求应届毕业生面试时自我介绍范文

天天快看:4月17日基金净值:建信鑫瑞回报灵活配置混合最新净值1.0512,涨0.02%

今日快看!一马当先指是什么生肖,答案作解

焦点信息:ChatGPT陷入“四面楚歌”?欧洲议会有意在AI法案中加强监管

达洛特:外界很多噪音但我们展现了个性 曼联在朝目标前进

Pixso 上线 Realibox 插件,设计师一键套用 3D 样机!

如何预防职业病?这个健康检查不能少

天天实时:ST新城全资子公司签订设备销售合同 总金额6.29亿元

职场十大困惑,你是否遇到过,怎么解决呢

通讯!情况通报

位于法国阿尔卑斯山顶部的水晶圆顶内是保时捷卡宴

全球今日报丨数字认证:在车联网密码安全领域技术已逐渐成熟并开始商业化落地

吴忌寒旗下加密货币挖矿平台 “比特小鹿”在美上市,首日暴跌30%

河南安阳:工匠精神助力经济“加速跑”

香港联交所建议优化ESG信息披露,进一步符合国际信披要求

铁路水路联手 物流降本增效(政策解读)

【时快讯】最后一个比赛日:中国队再夺跳水世界杯三金

世界头条:已经极速退款但是卖家拒收有影响吗 已经极速退款但是卖家拒收有影响吗怎么办

最资讯丨期货和股票的关系

快讯:陈亚男陈萌同时怀孕!朱小伟带媳妇看前妻,大衣哥约会情人被抓

鞍山到北京2550火车票余票查询 火车票余票查询

要闻:超级碰撞!林诗栋澳门赛首轮单挑张本智和,日本一哥或一轮游?

【速看料】甲午国殇·民族复兴主题教育标点符号哪错了_甲午国殇

环球热议:为了能够掌握权力,武则天可谓是将手段尽数施展出来!

下周河南多地将迎30℃+,东部南部注意防范强对流

焦点要闻:真快,iOS 16.4 验证已关闭,但仍然可升级

久违了美人!迭戈-科斯塔回归英超19场915分钟终破荒!

环球短讯!第八个全民国家安全教育日 各地各部门多形式普及总体国家安全观

全球热推荐:简易蛋挞液的做法图解_简易蛋挞的制作方法

当前消息!门前抢点破门,恩德里克打进巴甲新赛季首球

全球观焦点:最高补助90万元,“大搬快聚”试点村群众领到购房补助啦!

多名学生被曝取快递后申请仅退款具体是什么情况

果然视频丨潍坊举办“共建美丽幸福河湖”志愿服务活动启动仪式