(资料图片)
在此之前,去看了下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实现的,也不太想换
车谷中心城|川江池片区土地征收成片开发方案,川江,中心城,沿河村,土地征收,土地使用权
在没有追梦和小佩顿的情况下赢了!库里:这是我们应该做的,勇士,小佩顿,美国篮球,斯蒂芬·库里,这是我们...
上海车展是今年上半年国内汽车行业最重磅的大事件,各大车企也是纷纷在车展期间发布新技术,亮相新车型。作
中国地震台网正式测定:04月22日13时04分在台湾海峡南部(北纬22 57度,东经118 47度)发生4 7级地震,震
为进一步提高群众防范各类电信诈骗意识,预防和减少电信网络诈骗案件发生,近日,贵州石阡长征村镇银行积极
“T3出行要成为自动驾驶时代的核心运营商,这是我们的终极定位。”T3出行CEO崔大勇对《证券日报》记者表...
本报讯(记者王斌)4月21日,2023北京牡丹文化节开幕。北京青年报记者获悉,今年牡丹文化节首次联合津冀两
出品|何玺排版|叶媛比亚迪再次出圈。在4月18日上海车展的开幕首日上,比亚迪上宣布仰望U8豪华SUV开始预售,
笔记本电脑启动时就卡死(笔记本电脑启动时就卡死了)很多网友不太清楚我们的笔记本电脑一开机就死机的情况,
而端午节正好是制曲的最佳时节,因为在端午节前后,气温适宜、湿度较高、气压稳定,这些条件利于曲菌的生
今天来聊聊关于中药调理早些泄一般多长时间,中药治疗早泄的文章,现在就为大家来简单介绍下中药调理早些泄
EI CFG修改法是一种通过修改系统文件ei cfg来激活Windows系统的方法。ei cfg文件是Windows系统用于存储产品
2023上海车展期间,奥迪S4Avant正式首发亮相。新车此前已经开启了预订,预计将在今年4月份正式上市交付。作
泽连斯基在公开表态中是这么说的:现在是时候邀请乌克兰加入北约了。不久之前,乌克兰驻英国大使也就乌克
交易商品牌 产地交货地最新报价丁二烯橡胶 含量99%以上,优等品济南金锦泉经贸有限公司山东山东省14500元 吨
随着云南省大理白族自治州宾川县沃柑成熟上市,当地“果业新农人”中的“采果队”开始出动,他们拿着剪...
还把生活和兴趣相结合,成了半个网红,但她没有直播带货,而是纯粹分享好物和生活,素颜、自然不刻意,比起
中央气象台4月22日06时继续发布强对流天气蓝色预警:预计4月22日08时至23日08时,贵州中西部、云南东南部、
欢迎观看本篇文章,小勉来为大家解答以上问题。心绪不宁的宁什么意思,心绪不宁释义很多人还不知道,现在让
X 关闭
X 关闭