针对RedisTemplate分布式锁实现WatchDog 通讯

2023-04-22 10:48:48 来源: 腾讯云


(相关资料图)

在此之前,去看了下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-04-22 10:26
要闻   2023-04-22

全球今热点:北京中关村东升科技园完善创新企业服务生态——

拥有7家上市企业、43家瞪羚企业、81家中关村高新技术企业;2022年,园区产值达328亿元、税收29亿元……在北

发布时间: 2023-04-22 10:30
要闻   2023-04-22

车祸后仅4天 因莫比莱已重返训练

据意大利媒体《全市场》援引罗马当地媒体LaLazioSiamoNoi报道,此前遭遇车祸的拉齐奥队长因莫比莱已经恢复训练。

发布时间: 2023-04-22 09:58
要闻   2023-04-22

恒指牛熊街货比(67.4:32.6)︱4月22日|观热点

智通财经获悉,截至4月22日,恒指最新的牛熊街货比例为67 4:32 6。法兴恒指牛熊证街货分布图中的数据显示,

发布时间: 2023-04-22 09:21
要闻   2023-04-22

村淘和淘宝有什么区别_村淘和淘宝区别是什么

欢迎观看本篇文章,小勉来为大家解答以上问题。村淘和淘宝有什么区别,村淘和淘宝区别是什么很多人还不知道

发布时间: 2023-04-22 08:50
要闻   2023-04-22

热点 推荐

针对RedisTemplate分布式锁实现WatchDog 通讯

在此之前,去看了下Redission的实现原理,不过在开发中,原本的代码使用RedistTemplate实现的,也不太想换

发布时间: 2023-04-22 10:48
国内   2023-04-22

环球短讯!基层官兵轮休,关注!

“幸福班车”来了新疆军区某边防团轮休官兵乘坐班车准备出发(李雅蓉摄)“快看,‘幸福班车’来了!”随着

发布时间: 2023-04-22 10:26
要闻   2023-04-22

天天速读:工信部:对大型、超大型数据中心开展能效专项监察

近日,工业和信息化部办公厅发布《关于组织开展2023年度工业节能监察工作的通知》(以下简称《通知》)。《

发布时间: 2023-04-22 10:27
科技   2023-04-22

“五一”旅游热度持续高涨 预订火爆

目前,多个热门旅游城市的酒店预订已经非常火爆。旅游市场普遍反映,今年“五一”旅游市场需求释放得格外早

发布时间: 2023-04-22 10:33
IT   2023-04-22

全球今热点:北京中关村东升科技园完善创新企业服务生态——

拥有7家上市企业、43家瞪羚企业、81家中关村高新技术企业;2022年,园区产值达328亿元、税收29亿元……在北

发布时间: 2023-04-22 10:30
要闻   2023-04-22

一个u盘可以装winpewin10-(一个u盘可以装w7和w10吗) 全球今

一个u盘可以装winpewin10(一个u盘可以装w7和w10吗)关于如何使用USB在新计算机上安装win10系统?那么你找对

发布时间: 2023-04-22 10:23
科技   2023-04-22

笔记本电脑启动时就卡死-(笔记本电脑启动时就卡死了) 独家

笔记本电脑启动时就卡死(笔记本电脑启动时就卡死了)很多网友不太清楚我们的笔记本电脑一开机就死机的情况,

发布时间: 2023-04-22 10:06
IT   2023-04-22

头条焦点:路虎揽胜运动版SV将于5月31日正式发布

[本站资讯]日前,路虎官方宣布,旗下高性能SUV揽胜运动版SV将于5月31日正式发布。据此前外媒消息,新车将搭

发布时间: 2023-04-22 10:08
汽车   2023-04-22

能模拟换挡 现代Ioniq 5 N将于7月亮相

[本站资讯]日前,现代官方表示Ioniq5N将会在7月13-16日举办的古德伍德速度节期间正式亮相。作为Ioniq5的高

发布时间: 2023-04-22 10:09
汽车   2023-04-22

短讯!佳讯飞鸿:实际控制人之一郑贵祥拟减持不超过1.99%

4月21日电,佳讯飞鸿公告,实际控制人之一郑贵祥拟以集中竞价方式减持公司股份不超过1180万股,占公司目前

发布时间: 2023-04-22 10:16
国内   2023-04-22

车祸后仅4天 因莫比莱已重返训练

据意大利媒体《全市场》援引罗马当地媒体LaLazioSiamoNoi报道,此前遭遇车祸的拉齐奥队长因莫比莱已经恢复训练。

发布时间: 2023-04-22 09:58
要闻   2023-04-22

要闻速递:老板转正?56岁朱骏重出江湖 加盟橘橙足球队征战

北京时间4月29日,新赛季中冠联赛即将开打,56岁的前上海申花投资人朱骏出现在上海赛更达俱乐部橘橙足球队

发布时间: 2023-04-22 10:06
科技   2023-04-22

手感滚烫!老鹰半场轰下74分 创队史季后赛得分纪录

今日进行的NBA季后赛,老鹰半场74-67领先凯尔特人。

发布时间: 2023-04-22 10:00
IT   2023-04-22

【全球速看料】长丰县罗塘乡:三强化推进老有所学行动

中国农科新闻网是农业科技报社顺应网络时代新媒体发展趋势,在三农领域倾心打造的集资讯、互动、网上展示于

发布时间: 2023-04-22 09:49
国内   2023-04-22

广宇集团:2022年实现营业收入60.20亿元|今日观点

广宇集团:2022年实现营业收入60 20亿元-4月21日,广宇集团发布2022年年度报告。

发布时间: 2023-04-22 09:34
国内   2023-04-22

如何制作 5 人啤酒漏斗

你需要的东西漏斗,64盎司。或更大塑料管,11到16英尺(直径由个人选择决定)5个PVC球阀(与管径相同)8个

发布时间: 2023-04-22 09:33
国内   2023-04-22

恒指牛熊街货比(67.4:32.6)︱4月22日|观热点

智通财经获悉,截至4月22日,恒指最新的牛熊街货比例为67 4:32 6。法兴恒指牛熊证街货分布图中的数据显示,

发布时间: 2023-04-22 09:21
要闻   2023-04-22

【环球播资讯】事关地球上的每个生命!这些行动背后,藏着TA

今天(2023年4月22日)是第54个世界地球日人类共存于蔚蓝色的星球纵横的山谷是大地的脉搏翻涌的海洋是宇宙

发布时间: 2023-04-22 09:17
科技   2023-04-22

10倍提升 安卓新旗舰放弃祖传USB2.0:体验变化太明显了-世

快科技4月22日消息,各家的智能手机现在主要是拼处理器、拍照、电池等,但有个小地方多年来都没啥变化,那

发布时间: 2023-04-22 09:25
IT   2023-04-22

上海今年首轮土拍溢价率超7% 近八成地块进入“一次性报价区

4月21日,上海完成了为期四天的2023年首轮集中土拍,挂牌的19宗地均成功出让,总建筑面积为198 9万平方米,

发布时间: 2023-04-22 09:03
国内   2023-04-22