【资料图】
在此之前,去看了下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的实现原理,不过在开发中,原本的代码...
1、2015手机版QQ查看收藏方法 步骤:1:登陆手机QQ2:点击QQ界面下...
1、第一部:猎杀红色十月TheHuntforRedOctober(1990)第二部:爱国者游戏Pat
卫衣什么颜色好看今年卫衣流行什么颜色,对于臃肿厚重的秋冬来说,...
近日,四川天华股份有限公司举办“三十正青春 发展正当时”职工书...
济南高新控股股东高新城建解除冻结7 71%股份
残障童装的发展与国家的扶持政策和宣传推广有着密不可分的关系,尽...
一位网友给小米创办人雷军留言,小米13Ultra摄影套装全平台都没货。...
据媒体报道,近日,有网友反映上海车展安检扫描后会要求开包检查是...
格隆汇4月21日丨三大指数午间集体收跌,沪指跌1 11%,报3329点,深...
【电缆网讯】国内原料释放有限,现货交投氛围转暖,下游轮胎开工...
4月21日消息,亚马逊宣布推出防伪交易所(ACX),这是一项行业合作...
燕京啤酒04月21日在投资者关系平台上答复了投资者关心的问题。请问...
购车申请书范文第1篇尊敬的**:您好,我是XXXX员工XX,我XXX年XX月...
运行车合同范本第1篇甲方:乙方:兹因甲方工程需要,向乙方租赁运输...
以案说法丨滥用“背靠背”条款拒绝支付工程款,法院判决支付!
一学校被投诉!教育局介入调查
环己基三苯基溴化膦,关于环己基三苯基溴化膦介绍这个很多人还不知...
三大运营商一季度净赚383亿元:产业数字化业务营收增长提速,数字化,...
1、病情分析:脱肛是直肠黏膜脱垂,包括黏膜脱垂和全层直肠脱垂。2...
很多人都会选择在闲暇的时间里去钓鱼消遣时间,但是对于新手而言,...
小区10余颗树木被砍物业称都是“死树”
每日甘肃网讯(新甘肃·每日甘肃网记者 万及敏)4月19日,记者从省...
江海股份00248404月21日在投资者关系平台上答复了投资者关心的问题...
行业主要上市公司:许继电气(000400)、国电南瑞(600406)、金风科技(...
香港中华厂商联合会马来西亚交流团,昨天与马来西亚国际贸易及工业...
截至2023年4月20日收盘,人民网(603000)报收于23 74元,上涨6 84%...
App4月19日消息,维力医疗4月19日晚间披露年报,2022年实现营业收入...
App4月20日消息,浙江省政府办公厅近日印发《关于进一步扩大消费促...
“我是吸引钱的磁铁,我爱钱,钱也爱我,我每天都在接收钱。”在浙...