当前位置:首页>焦点 > 正文

针对RedisTemplate分布式锁实现WatchDog 当前简讯

  • 2023-04-21 15:27:20来源:腾讯云


(资料图)

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

讯息:全国首针!在长春接种完成!这种病尚无特效药,疼痛程度可达10级

20日,国内首个适用于40岁及以上人群的带状疱疹减毒活疫苗在长春市净月区富奥社区卫生服务中心预防接种门诊

鄂尔多斯市气象台发布道路结冰黄色预警【III级/较重】

鄂尔多斯市气象台发布道路结冰黄色预警【III级 较重】

我国确定12项“十四五”中医药文化弘扬工程重点任务 全球短讯

中医药学是中国古代科学的瑰宝也是打开中华文明宝库的钥匙《“十四五”中医药文化弘扬工程实施方案》4月19

天天速讯:新东方三季报,已不止东方甄选?

在教育业务全线复苏,东方甄选已由“雪中送炭”变成“锦上添花”。撰文|胡莹日前,新东方交出了截至2023年2

环球新消息丨餐饮复苏向好之势愈发明显(记者手记)

晚上7时许,在面条店的采访暂告段落,沿明瓦廊北端南行,逛至大香炉,再经小板巷穿行至丰富路,继续北行。

聚焦:内蒙古扑灭中俄和中蒙边境火明火

内蒙古扑灭中俄和中蒙边境火明火

移动机顶盒刷机教程移动_移动机顶盒刷机教程_天天快讯

1、先安装刷机工具软件:PhoenixSuitPacket,安装后会在桌面生成快捷方式,双击图标。2、2、点击工具栏第二

全球快讯:【国际快讯】特斯拉市值蒸发超500亿美元;马斯克暗示会继续降价;特斯拉一季度营收增长24%

【国际快讯】特斯拉市值蒸发超500亿美元;马斯克暗示会继续降价;特斯拉一季度营收增长24%特斯拉一季度营收

【大运倒计时】成都大运会誓师大会召开,吹响青春“集结号”!

原标题:【大运倒计时】成都大运会誓师大会召开,吹响青春“集结号”!誓师大会现场誓师大会现场四川新闻网

天天视点!女演员发文安利电影《灌篮高手》:不想和没看过全国大赛的人说话了

4月20日凌晨,演员田曦薇发博安利电影《灌篮高手》,配文“已经不想和没看过全国大赛的人说话了”,还在评

环球今头条!教育“调味”要适度

日前,笔者在基层调研思想政治教育情况时,发现个别干部在授课时引用网言网语和热门梗有些过多过滥,而具有

爆炸输出!加兰半场三分6中4&罚球11中10狂揽26分 正负值高达+22|焦点速递

NBA季后赛首轮G2,骑士半场结束59-39领先尼克斯20分之多。上半场比赛可谓是加兰的个人进攻秀,他外线手感火

怡亚通:卓怡恒通目前IPO正常推进中

怡亚通4月19日在互动平台表示,合肥市卓怡恒通信息安全有限公司为公司联营企业,目前正在IPO的正常推进中。

珀莱雅一季度护肤类产品实现营收13.85亿元 今热点

新京报贝壳财经讯4月20日,珀莱雅化妆品股份有限公司(以下简称“珀莱雅”)发布2023年第一季度主要经营数

3350点之上继续做多!-热资讯

收盘了,大盘收跌百分之0 09点,报收3367点十字星,创业板收跌百分之1 20点,报收2386点中阴线!两市个股再

阿坎吉:效力过多特的我更想击败拜仁 看过首回合就不会批评索默 世界通讯

曼城首回合3-0获胜,球队后卫阿坎吉对德媒《图片报》谈到了他对淘汰拜仁的渴望、队友哈兰德的表现、对手门

全球今热点:K77社媒:很难过无法给那不勒斯球迷带来快乐,我们的梦还在继续

K77社媒:很难过无法给那不勒斯球迷带来快乐,我们的梦还在继续,快乐,米兰,欧冠,那不勒斯,我们的梦

蒋梦婕用法律武器反击偷拍勒索,是一个良好示范|新京报快评-微头条

▲蒋梦婕公布的遭受勒索私信截图。图 蒋梦婕微博女明星被偷拍裙底,图片在互联网上广泛传播,这样的事件不

天士力:4月20日融资买入1348万元,融资融券余额5.55亿元

4月20日,天士力(600535)融资买入1348 0万元,融资偿还804 83万元,融资净买入543 17万元,融资余额5 35

台盆尺寸窄了怎么补救_台盆尺寸 世界观焦点

1、(长*宽百*高,单位:mm)500×430×450:这个洗脸盆尺寸一般是挂盆常用的尺寸,适合小户型家居使用,能够有效

迈尔斯谈追梦被禁赛:重点不是我们怎么想 这就是最终结果_全球观速讯

迈尔斯谈追梦被禁赛:重点不是我们怎么想这就是最终结果,勇士,意大利篮球,国际篮球赛事,卡尔顿·迈尔斯,奥

环球热推荐:湖南省网络作协第二届会员代表大会举行 余艳当选新一届主席团主席

4月20日,湖南省网络作家协会第二届会员代表大会在长沙举行。湖南省网络作家协会第二届主席团成员合影留念

全球今头条!川警风采丨百日倒计时 民警讲述护航大运会背后的故事

封面新闻记者田之路吴正友是成都市公安局龙泉驿区分局治安科一级警长,荣立个人三等功3次、获得个人嘉奖6次

天天热讯:城市微光 | 小饭馆贴出“免费吃面”提示,让每一位受助者“暖胃又暖心”

郑报融媒把握正确舆论导向,关注百姓生活,侧重报道社会生活中的知识性、趣味性、服务性新闻;突出新闻性、

环球最新:英文名字中间的圆点符号 英文名字中间的圆点怎么打

今天来聊聊关于英文名字中间的圆点符号,英文名字中间的圆点怎么打的文章,现在就为大家来简单介绍下英文名

美财政部现金收入大幅不及预期,或提前触及债务上限 全球微资讯

美国银行称,根据历史先例,纳税日后财政部现金储备增加超过2000亿美元将是强劲的,而低于1500亿美元的数字

新人未出席婚礼父母致辞20秒开席具体是什么情况 世界看热讯

很多人对新人未出席婚礼父母致辞20秒开席具体是什么情况比较关心,现在让我们一起来瞧瞧具体是什么情况吧!

全球热头条丨2023年兰州中考“一诊”分析结果出炉 城市四区96所学校26283人参加

2023年兰州中考“一诊”分析结果出炉城市四区96所学校26283人参加

此功能netscape用户不能使用 当前浏览器netscape不支持控件 世界观速讯

今天来聊聊关于此功能netscape用户不能使用,当前浏览器netscape不支持控件的文章,现在就为大家来简单介绍下此

猜您喜欢

    Copyright ©  2015-2022 世纪服装网版权所有  备案号:京ICP备2021034106号-22   联系邮箱:55 16 53 8@qq.com