针对RedisTemplate分布式锁实现WatchDog 当前独家

2023-04-21 16:17:36 来源:腾讯云


【资料图】

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

蜘蛛侠:英雄远征 电影迅雷_蜘蛛侠:英雄远征 2020年华东理工大学出版社出版的图书-焦点速看

2023-04-21

世界短讯!小乐敦眼药水适合多大孩子_小乐敦眼药水说明书及用量

2023-04-21

新疆省造大清银币价格(2023年04月21日)

2023-04-21

世界快播:韩国艺人黄仁烨郑采妍将携手出演新剧《组合式家族》,将在不久后开拍

2023-04-21

国际投行密集上调中国GDP增速预测值 海外投资者对华投资信心持续提升

2023-04-21

长梁山隧道加紧施工保贯通_全球热点

2023-04-21

每日热讯!荔城北大村:打造旅游新业态 村庄焕发新魅力

2023-04-21

全球快资讯丨泓德基金管理有限公司旗下部分基金2023年第一季度报告提示性公告

2023-04-21

全球观察:第十三届国家综合防灾减灾与可持续发展论坛在雅安举办

2023-04-21

周朴园人物形象分析简答 周朴园人物形象分析

2023-04-21

听风就是雨什么意思|环球今日讯

2023-04-21

头条焦点:Canalys:Q1印度智能手机市场出货量同比下降20% 史无前例

2023-04-21

施甸文旅融合带火乡村经济

2023-04-21

当前热讯:异动快报:*ST深南(002417)4月19日14点48分触及跌停板

2023-04-21

萝卜泡菜配方窍门_萝卜泡菜做法

2023-04-21

全球快播:新车报讯:上汽大众ID.6X参数曝光续航里程588km

2023-04-21

美锦能源:4月20日融资买入3497.06万元,融资融券余额14.41亿元

2023-04-21

每日快讯!Siri的创始人们去了三星带着自己的新语音助手

2023-04-21

洁特生物:4月20日融资买入500.82万元,融资融券余额7330.77万元

2023-04-21

油电并行:全新探歌,替燃油车打个样-每日快讯

2023-04-21

每日快播:海南机场:2022年度净利润约18.56亿元,同比增加300.68%

2023-04-21

AMDRA400北极群岛系列显卡将于明年发布 天天速看料_全球视讯

2023-04-21

当前速读:怎样去除脂肪粒最有效的方法_怎样去除脂肪粒

2023-04-21

短讯!苏敏出事了,房车被扣居无定所,说出不离婚的内幕

2023-04-21

全球被做空最严重银行!多伦多道明银行空头头寸升至61亿美元

2023-04-21

光驱启动怎么设置快捷键_光驱启动怎么设置

2023-04-21

建业地产:3笔票据交换要约及同意征求已届满,将发行约7.58亿美元新票据

2023-04-21

世界短讯!T恤+阔腿裤,入夏最时髦搭配!

2023-04-21

世界快讯:心怀山河不负春 研学旅行筑梦行

2023-04-21

Copyright ©  2015-2022 人人频道网版权所有  备案号:粤ICP备18023326号-36   联系邮箱:8557298@qq.com