短讯!针对RedisTemplate分布式锁实现WatchDog

2023-04-21 16:28:06 来源:腾讯云 分享到:


【资料图】

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

来源:腾讯云 2023-04-21 16:28:06

天天热点评!楚人的瘦美风尚与服饰文化探究

来源:中国文化报 2023-04-21 16:12:23

环球快讯:什么是著名的吉普赛食品?

来源:太平洋礼物网 2023-04-21 15:11:15

全球信息:关口前移,失能失智可预防!青岛市精心打磨“长护险”十一载,走在前列提供“青岛样本”

来源:半岛都市报 2023-04-21 15:01:20

【天天时快讯】国安队意难平

来源:北京晚报 2023-04-21 15:00:00

全球看点:工信部:工业互联网核心产业规模超1.2万亿元

来源:中央广电总台央视新闻客户端 2023-04-21 15:01:59

每日快讯!山泉小学喜获首批成都市中医药文化传承基地授牌

来源:百姓生活官方号 2023-04-21 14:59:52

每日看点!“两步走”思路,广州计划这样治理和活化生活垃圾填埋场

来源:金羊网 2023-04-21 14:40:29

快资讯:广西龙胜第九届龙脊国际梯田文化旅游节开幕

来源:中国日报网 2023-04-21 13:47:18

环球热议:京津物流园打造三地“城市冰箱”

来源:消费日报 2023-04-21 13:43:38

环球快报:新龙江 新故事|候静波,心脏病介入领域的“铁娘子”

来源:黑龙江日报 2023-04-21 13:26:14

头条焦点:北京经开区加快建设全球“新药智造”产业高地

来源:北京亦庄创新发布 2023-04-21 12:40:00

每日消息!公开曝光违法案例

来源:阜阳日报 2023-04-21 12:32:33

每日速讯:粉身碎骨浑不怕要留清白在人间写的是哪位清洁工_粉身碎骨浑不怕要留清白在人间写的是

来源:科学教育网 2023-04-21 12:17:19

天天短讯!家用蒸箱哪个牌子好_家用蒸箱

来源:互联网 2023-04-21 12:14:46

全球信息:V 模型:汽车电子系统开发的开发流程

来源:汽评网 2023-04-21 11:19:15

全球微速讯:砍下40分!马龙盛赞穆雷:这是一场热烈且直击心灵的演出

来源:直播吧 2023-04-21 11:09:46

快消息!新车报讯:将于8月上市五菱征程实车图曝光

来源:互联网 2023-04-21 10:44:03

环球信息:成渝RCEP跨境贸易中心在重庆两江新区成立

来源:封面新闻 2023-04-21 10:26:35

焦点资讯:王玉祥:加强新市民金融服务是互联网保险重点发展方向

来源:中新经纬 2023-04-21 10:06:59

播报:孙颖莎逆转韩莹,王艺迪艰难取胜迪亚兹| WTT澳门冠军赛

来源:乒乓世界 2023-04-21 09:48:11

世界最新:北京两宗地块土拍规则升级 禁止多马甲竞拍

来源:北京买房人 2023-04-21 09:18:40

世界头条:苏宁易购与倍科达成重磅战略合作

来源:36氪 2023-04-21 09:30:28

每日看点!计算机内部数据加工处理和传输的形式是_计算机内部 数据加工 处理 传送的形式是A 十六进制B 十进制C 八

来源:互联网 2023-04-21 08:15:25

焦点热议:特斯拉:画饼大年、落地小年,“长情陪伴” 太难了

来源:钛媒体APP 2023-04-21 07:50:18

热门看点:北京公交:4月26日起新开、调整、撤销部分怀柔区域线路

来源:新京报 2023-04-21 07:41:15

世界今热点:“鸽子花”开迎客来

来源:新华社新媒体 2023-04-21 07:20:28

当前速看:局势升级!埃及对俄“背后捅刀”?开足马力给乌军生产导弹

来源:战旗红 2023-04-21 07:13:13

全球热资讯!3660安全浏览器_3660安全卫士官网

来源:互联网 2023-04-21 07:00:01

全球速读:美媒列出史上胜率最高的50人,詹姆斯掉出前30名,伦纳德排第三

来源:阿雄侃篮球 2023-04-21 06:31:26

Copyright   2015-2022 纵横知识产权网 版权所有  备案号:浙ICP备2022016517号-12   联系邮箱:51 46 76 11 3 @qq.com