針對(duì)RedisTemplate分布式鎖實(shí)現(xiàn)WatchDog
來源:騰訊云 2023-04-21 16:27:32
(相關(guān)資料圖)
在此之前,去看了下Redission的實(shí)現(xiàn)原理,不過在開發(fā)中,原本的代碼使用RedistTemplate實(shí)現(xiàn)的,也不太想換,所以我想了下,不如自己實(shí)現(xiàn)要給WatchDog。
我的想法是,在用戶加上鎖的時(shí)候開啟個(gè)定時(shí)任務(wù)線程,并且在定時(shí)任務(wù)中,判斷原線程isAlive狀態(tài)進(jìn)行“續(xù)命”。
下面是代碼(在這里面為了方便,未使用的是HuTool.CornUtil來實(shí)現(xiàn)動(dòng)態(tài)定時(shí)任務(wù)):
/** * Title * * @ClassName: LockUtil * @Description:鎖工具類,通過內(nèi)部枚舉類實(shí)現(xiàn)單例,防止反射攻擊 * @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; /** * 帶看門狗機(jī)制上鎖 * @param lockObj * @return */ public boolean DistributedLock(Object lockObj){ try { return DistributedLock(lockObj,null,null); } catch (KaToolException e) { throw new RuntimeException(e); } } @Resource LockConfig lockConfig; //加鎖 /** * 無看門狗機(jī)制上鎖 * @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); //實(shí)現(xiàn)看門狗 if (isDelay){ if (LockUtil.isOpenCorn==false){ //如果同一個(gè)項(xiàng)目之前打開過,那么先關(guān)閉,避免重復(fù)啟動(dòng) CronUtil.stop(); //支持秒級(jí)別定時(shí)任務(wù) CronUtil.setMatchSecond(true); //定時(shí)服務(wù)啟動(dòng) 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); } //利用枚舉類實(shí)現(xiàn)單例模式,枚舉類屬性為靜態(tài)的 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; }}
關(guān)鍵詞:
圖片版權(quán)歸原作者所有,如有侵權(quán)請(qǐng)聯(lián)系我們,我們立刻刪除。
新化月報(bào)網(wǎng)報(bào)料熱線:886 2395@qq.com
新化月報(bào)網(wǎng)報(bào)料熱線:886 2395@qq.com
相關(guān)文章
你可能會(huì)喜歡
最近更新
- 針對(duì)RedisTemplate分布式鎖實(shí)現(xiàn)WatchDog2023-04-21
- Python面向?qū)ο缶幊?三大特性-繼承-單繼承2023-04-21
- Consul 簡(jiǎn)單示例2023-04-21
- 熱點(diǎn)評(píng)!Python面向?qū)ο缶幊?魔術(shù)方法-__call__和__getattr__方法2023-04-21
- 使用車載空調(diào)該注意什么?車載空調(diào)的工作原理是是什么?2023-04-21
- 池西區(qū)應(yīng)急局開展2023年汛前災(zāi)害信息員培訓(xùn)班|每日?qǐng)?bào)道2023-04-21
- 如何去除地板異味?擦地板要用什么清潔劑?2023-04-21
- 環(huán)球快訊:錢報(bào)健康小站丨錯(cuò)把精華液當(dāng)眼藥水,大伯差點(diǎn)失明,這事千萬注意2023-04-21
- 世界速訊:“啃讀挑戰(zhàn)”打造區(qū)域教師教育“金字招牌”2023-04-21
- 臺(tái)州市路橋區(qū)氣象臺(tái)發(fā)布大風(fēng)黃色預(yù)警【Ⅲ級(jí)/較重】 當(dāng)前要聞2023-04-21
- 北京市臍血庫(kù)第五次通過血液與生物治療促進(jìn)協(xié)會(huì)AABB復(fù)審2023-04-21
- 惠潤(rùn)攜手中國(guó)綠化基金會(huì),以植愈之力守護(hù)綠色2023-04-21
- 天天速看:預(yù)防癌癥三步走2023-04-21
- 省級(jí)科研實(shí)驗(yàn)室落戶 名優(yōu)茶采摘機(jī)初亮相?“科技+機(jī)械” 引領(lǐng)余杭農(nóng)業(yè)高質(zhì)量發(fā)展 天天看點(diǎn)2023-04-21
- 珈瑪高端數(shù)控加工中心,給您提供專業(yè)的永續(xù)服務(wù)2023-04-21
- 擁抱F5.5G,華為將打造全光萬兆之城五大場(chǎng)景 簡(jiǎn)訊2023-04-21
- 【環(huán)球熱聞】答復(fù)|餐飲經(jīng)營(yíng)者是否可以以農(nóng)村群體聚餐的形式從事餐飲經(jīng)營(yíng)活動(dòng)2023-04-21
- 平定縣氣象局發(fā)布大風(fēng)藍(lán)色預(yù)警【Ⅳ級(jí)/一般】|天天觀察2023-04-21
- 世界速看:誰是鄂州最佳“剪刀手”?這場(chǎng)比賽有看頭2023-04-21
- 世界觀察:首屆中歐綠色創(chuàng)新發(fā)展大會(huì)在江門舉辦2023-04-21
- 商湯絕影許亮:和汽車"商量" 創(chuàng)建艙內(nèi)場(chǎng)景新生態(tài) 世界報(bào)資訊2023-04-21
- 河口街道:人間最美四月天 解鎖社區(qū)美好答案2023-04-21
- 春風(fēng)行動(dòng)|“零距離”服務(wù)企業(yè) “心連心”綠色幫扶2023-04-21
- 河北:電網(wǎng)春季忙“體檢” 迎峰度夏早準(zhǔn)備2023-04-21
- 雄安新區(qū):第二季度43個(gè)重點(diǎn)項(xiàng)目集中開工 總投資268億元_快資訊2023-04-21
- 請(qǐng)?zhí)崆靶钏?!今天武漢這個(gè)區(qū)域?qū)⑼K甠環(huán)球看熱訊2023-04-21
- 江河集團(tuán)(601886)4月21日主力資金凈賣出214.65萬元 全球微速訊2023-04-21
- 《酒釀美好》新書發(fā)布:郎酒新篇章背后的三品路徑2023-04-21
- Whale帷幄發(fā)布“人機(jī)協(xié)作”Alivia,AGI重塑營(yíng)銷科技新范式-世界實(shí)時(shí)2023-04-21
- MIFU(米夫),真正的美國(guó)進(jìn)口品牌!2023-04-21