针对RedisTemplate分布式锁实现WatchDog 世界球精选
来源:腾讯云    2023-04-23 02:44:45


【资料图】

在此之前,去看了下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实现的,也不太想换

2023-04-23

发现市州最美图书馆·雅安丨青衣江畔,...

雅安观察罗光德黄刚川观新闻记者薛维睿 文 图4月21日,雅雨蒙蒙,青衣江与陇西河口交汇不远处,雅安市图书

2023-04-23

播报:少儿医保可以直接去医院看病吗?...

孩子出生之后就应该去给孩子买少儿医保,少儿医保对于孩子来说还是非常的重要的,以后看病报销什么的我们都

2023-04-23

全球新消息丨2023上海车展:新款林肯冒...

2023年上海车展上,新款林肯冒险家正式发布。作为中期改款车型,新车采用了更新的设计以及内饰细节。

2023-04-23

骨骺线闭合怎么看求图片_骨骼线闭合怎么...

1、一般来说想要看一看自己的这个骨骼线是否是闭合了的,最最常规的一种方法就是去医院拍X线片,这是最基本

2023-04-22

焦点短讯!石器时代攻略_石器时代新手攻略

1、首先,张英雄选择优惠券,可以从Knorpp的火属或风属中选择。2、卡拉龟必练,水陆属性飞龙必练,红朋克头

2023-04-22

河北证监局举办“走进资本市场第一课”...

近日,河北证监局联合深圳证券交易所,指导河北省上市公司协会举办“大河之北赋能远航”之“走进资本市场第...

2023-04-22

花光所有运气?枪手失争冠主动 天王山...

在本场比赛之前,阿森纳已经连续两场比赛遭遇平局,且都是2-0领先的情况下被扳平。对于阿尔特塔来说,球队

2023-04-22

山西洪远机械设备有限公司

山西洪远机械设备有限公司是一家致力于新型建材设备、工业固体废弃物处理设备和技术开发的专业公司。公司资

2023-04-22

出售出入境证件犯罪司法怎么认定 世界...

(一)本罪与组织他人偷越国(边)境罪或偷越国(边)境罪的界限本罪与其他俩罪的区别一般比较明显,但在行为人与

2023-04-22

紫陶和紫砂哪个煲汤好 紫砂跟陶瓷煲汤...

1、紫砂和陶瓷相比,紫砂煲汤比较好。2、用紫砂煲汤,营养不会流失,还能最大程度的保留食材的原汁原味,不

2023-04-22

【聚看点】中国移动(宁夏中卫)数据中...

中国移动(宁夏中卫)数据中心全力当好“领跑者”

2023-04-22

灼热武器材料_灼热武器

1、灼热武器暴击会触发重伤。2、但是:炽热板甲护手和风暴护手是每次攻击都会触发内伤害容效果。3、而灼热

2023-04-22

溆浦县举办第一届溆浦鹅肥肝烹饪大赛_环...

溆浦县举办第一届溆浦鹅肥肝烹饪大赛

2023-04-22

环球快资讯丨妲己铭文最强输出2022_妲己...

1、红色铭文:梦魇,法术攻击+4 2,法术穿透+2 4蓝色铭文:轮回,+2 4法攻、+1%法术吸血绿色铭文:怜悯,冷却缩

2023-04-22

迅雷打不开网页 迅雷打不开|环球关注

今天来聊聊关于迅雷打不开网页,迅雷打不开的文章,现在就为大家来简单介绍下迅雷打不开网页,迅雷打不开,

2023-04-22

今天打开个税APP,我直接人麻了!_简讯

点击上方“码农突围”,马上关注这里是码农充电第一站,回复“666”,获取一份专属大礼包真爱,请设置“星...

2023-04-22

焦点快看:华自科技(300490)4月10日股东...

近日华自科技披露,截至2023年4月10日公司股东户数为3 41万户,较3月31日增加1605 0户,增幅为4 94%。户均

2023-04-22

船记吐槽:最后赢得总冠军的球队可能需...

船记吐槽:最后赢得总冠军的球队可能需要健康的膝盖,快船队,恩比德,76人队,保罗-乔治,科怀·伦纳德

2023-04-22

资金流入CPO、手机游戏等板块

周四,沪深两市震荡调整。截至收盘,沪指跌0 09%报3367 03点,深成指跌0 37%报11717 26点,创业板指跌1 20%

2023-04-22