在此之前,去看了下Redission的实现原理,不过在开发中,原本的代码使用RedistTemplate实现的,也不太想换,所以我想了下,不如自己实现要给Wat
腾讯云 2023-04-22 06:07:07
(资料图片仅供参考)
在此之前,去看了下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实现的,也不太想换,所以我想了下,不如自己实现要给Wat
								1、燃放烟花爆竹产生的大气污染。2、燃放烟花爆竹产生的硝烟为“年味”。3、燃放烟花爆竹会产生二氧化硫、一氧化氮、二氧化氮
								鞭牛士4月21日消息,特斯拉股价周四下跌9 8%,市值蒸发556 9亿美元,跌幅超过了福特和通用的市值之和。而自从去年
								1、北方工业被毁。2、到现在还没恢复过来越南工业几乎在北方。3、一个国家的工业被毁这个国家你知道会是什么下场吧。本文为大
								一、题文下列关于alpha测试的描述中正确的是:A alpha测试需要用户代表参加B alpha测试不需要用户代表参加C alpha测试是系统测试的一种D al
								更多精彩内容和图文持续分享,欢迎关注和收藏。稳定扩散模型(StableDiffusionModels)是一种在自然语言处理(NLP)和计算机视觉领域的最新技
								福彩双色球第2023044期开出奖号:02、08、15、22、24、26+16。其中红球012路比为2:1:3,奇偶比为1:5,三区比为2:2:2,蓝球开出1路
								建工保利再度合作拿下莘庄热门地块,莘庄,杨浦,闵行区,印象城,保利地产,建工保利
								1、斯爵斯克莱德大学TheUniversityofStrathclyde主要有五个学院:艺术学院、商学院、
								在第28个世界读书日和新华书店成立86周年纪念日来临之际,由中宣部印刷发行局、中国出版集团有限公司指导,中国新华书店协会、新华书店总店有
								4月21日,南方军工改革灵活配置混合A最新单位净值为1 3575元,累计净值为1 3575元,较前一交易日下跌1 32%。历史数据显示该基金近1个月下跌2 8
								1、你去“幻熊结婚圈”上面看看。2、上面东西挺实在的。3、很适合你。本文就为大家分享到这里,希望小伙伴们会喜欢。
								格隆汇4月21日丨四创电子公布2022年年度报告,报告期实现营业收入27 21亿元,同比下降13 45%;归属于上市公司股东的净利润6603 72万元,同比下
								(相关资料图)新华社资料图美国白宫日前发布阿富汗撤军行动调查报告,承认在撤军过程中存在“巨大的情报失败”,将仓皇撤军责任
								点击链接查看详情央视网消息(焦点访谈):作为中国外贸的“风向标”和“晴雨表”,广交会因为其历史最长、规模最大、商品种类最全、到会客商