实时

您的位置:首页>资讯 >

【全球快播报】针对RedisTemplate分布式锁实现WatchDog


(相关资料图)

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

关键词:

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

2023-04-22 10:48:17

1、《孔子:汉韩对照》是2017年新世界出版社出版的图书。2、。文章到此就分享结束,希望对大家有所帮助。

2023-04-22 10:04:25

据国家突发事件预警信息发布网:琼中县气象台2023年04月21日14时36分发布高温橙色预警信号:我县3小时内最

2023-04-22 10:09:50

1、孔果藻属(Trematocarpus)为红藻门(Rhodophyta)杉藻目(Gigartinales)海木耳科

2023-04-22 09:36:18

1、所谓架立筋,就是为了绑扎箍筋而设置的钢筋。2、否则箍筋没有附着的点。3、根据受力计算,那里不需要受

2023-04-22 09:28:22

1、去临矿如果是在编职工,最好去临矿,临矿是省内煤炭企业改制最成功的一个。2、各方面都还不错。本文分享

2023-04-22 08:45:35

2023珠海鹤洲新区新青年城市花园保障房每月租金价格单身公寓:最低1159 92元 月二房一厅:最高2201 26元 月

2023-04-22 08:50:17

4月21日,无锡2023年第一批次集中出让,6宗地总起价60 1亿,总出让面积22 13万平方米,包括梁溪区(3宗)、

2023-04-22 08:24:01

十八里店西直河首创·繁星保租房周边交通有地铁公交吗?答:有,项目周边交通便利,形成了“双高速”、“双

2023-04-22 08:05:38

1、省图和金安都有针对少儿的绘本书,推荐省图。2、除此之外,哈工大对面(就在那个卖电脑的百脑汇上边)有

2023-04-22 07:38:10

进度查询入口:https: xn--pqq6m13b78ab4zuhdhhs9a70wbw0l xn--zfr164b cn gzfsq gzfspjdcx

2023-04-22 07:04:19

2023年4月7日纽威数控融资净偿还207 56万元,融资余额5194 3万元

2023-04-22 06:50:29

4月21日北向资金减持1000 3万股中国电力(02380 HK)。近5个交易日中,获南向资金减持的有4天,累计净减持5

2023-04-22 06:40:17

4月21日,“中国式现代化与世界”蓝厅论坛在上海“世界会客厅”举办。国务委员兼外长秦刚出席论坛开幕式并

2023-04-22 05:31:59

截至2023年4月21日收盘,中电环保(300172)报收于4 38元,下跌0 9%,换手率0 83%,成交量4 07万手,成交额1788 32万元。

2023-04-22 05:26:40

超95%收入来自“卖药”阿里健康用户增长明显放缓

2023-04-22 05:24:47

金洲管道2022年营收60 89亿净利2 35亿董事长孙进峰薪酬108 85万2023 4 2121:04:34挖贝网春雨挖贝网4月21日,金洲

2023-04-22 04:51:25

1、用料主料红薯淀粉100克调料生抽35克芝麻油15克辣椒油15克水450克红薯凉粉的做法1 红薯

2023-04-22 04:26:16

4月21日北向资金增持111 21万股宁德时代。近5个交易日中,获北向资金增持的有4天,累计净增持289 47万股。

2023-04-22 04:28:51

4月21日北向资金减持62 38万股万年青。近5个交易日中,获北向资金减持的有3天,累计净减持124 47万股。近20

2023-04-22 03:42:52