針對RedisTemplate分布式鎖實現WatchDog
2023-04-17 08:45:34 來源:騰訊云 小 中
(資料圖片)
在此之前,去看了下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
- 早知道:上市公司獨立董事制度全面改革;寧德時代鈉離子電池首發落地
- 廣發證券:AI投資會有一段時間調整期,下一階段依靠兩方面外界因素_全球快資訊
- 環球動態:華泰證券:關注AI大模型在終端側的輕量化應用
- 旺能環境:簽署《監利市餐廚垃圾綜合處理和資源化利用項目特許經營協議》|世界簡訊
- 環球微頭條丨中證報:因城施策持續顯效,樓市企穩跡象漸增
- 證券日報:旅游市場加快復蘇, “五一”出行熱度高漲
- 中信建投:光伏估值處于低位 看好一季報業績超預期方向_世界即時
- 馮柳192億“豪賭”,頂流逃離_熱點聚焦
- 全球新消息丨從明陽智能談談我的投資邏輯
- 所在城市龍頭乳企降維打擊已開始,其它乳企跟嗎?|世界百事通
- 【天天時快訊】高瓴最新持倉;有牛市
- 今日快訊:但斌深夜發聲回應言行不一:不干預旗下基金經理選擇投資標的
- 多地聚焦“數商興農” 政企合力助推鄉村振興
- 注冊制改革全面落地首周:市場運行平穩,制度優勢漸顯
- 天天快消息!廣發證券:AI投資會有一段時間調整期,下一階段依靠兩方面外界因素
- 國際油價攀高,國內成品油零售價將迎今年來最大漲幅|每日聚焦
- 天天熱點評!商務部:正推動內地香港澳門共建單一自貿區
- 布局財富管理市場 保險機構瞄準基金銷售牌照|全球報道
- 汽車智能化競速賽開啟 產業鏈加強合作
- 注冊制改革全面落地首周:市場運行平穩,制度優勢漸顯
- 世界百事通!我自研兆瓦級PEM制氫裝備性能進階
- 多地聚焦“數商興農” 政企合力助推鄉村振興
- 科研人員發現治療非酒精性脂肪肝的潛在新藥
- 經濟日報:把促進高校畢業生就業放在突出位置,要穩定公共崗位規模-環球訊息
- 全球速看:埃安旗下首款純電超跑Hyper GT開啟預售
- 文旅局長“卷”上天 出游數據狂飆_全球報資訊
- 世界滾動:但斌再度高調力挺茅臺
- 從年報透視A股公司“動力源”:研發大手筆,創新加速度|今熱點
- 自由港、淡水河谷、英美資源等礦業巨頭都在評估收購Teck Resources Ltd.基礎金屬業務的可能性
熱文推薦
排行推薦

旺能環境:簽署《監利市餐廚垃圾綜合處理和資源化利用項目特許經營協議》|世界簡訊
旺能環境(002034):簽署《監利市餐廚垃圾綜合處理和資... 更多>

環球微頭條丨中證報:因城施策持續顯效,樓市企穩跡象漸增
中指研究院認為,各地因城施策支持力度不斷增強,短期... 更多>

證券日報:旅游市場加快復蘇, “五一”出行熱度高漲
攜程旗下FlightAi市場洞察平臺數據顯示,截至4月14日... 更多>

中信建投:光伏估值處于低位 看好一季報業績超預期方向_世界即時
中信建投最新研報表示,市場對于光伏板塊預期悲觀,主... 更多>
世界今日報丨俄羅斯總統普京會見李尚福
據新華社,當地時間4月16日,俄羅斯總統普京在莫斯科... 更多>
全球今熱點:經濟日報:確保電力平穩迎峰度夏
文章稱,隨著社會生產生活快速恢復,今年迎峰度夏期間... 更多>
經濟日報:多渠道拓展國產大豆消費|全球滾動
國家糧食和物資儲備局科學研究院首席研究員李愛科撰文... 更多>
天天熱訊:國內成品油零售價將迎今年來最大漲幅,92號汽油每升上漲0.4元左右
受國際油價大幅攀升影響,國內汽柴油零售價結束連跌走... 更多>
【環球新視野】產業趨勢投資中,如何賺“認知差”的錢?
投資進化論系列:消除不確定性這一輪令人瞠目結舌的AI... 更多>
全球觀熱點:寫給所有散戶的一封信:換手率大于7%意味著什么?看懂少走彎路!
所謂市場,就是交易場所。市場本身不產生利潤。所謂賺... 更多>
上海誼眾紫杉醇聚合物膠束新增適應癥臨床獲批
$上海誼眾(SH688091)$從國家藥品監督管理局藥品評審中... 更多>
機構開始覆蓋光庫_觀點
光庫周五漲13 69%。機構覆蓋開始了。海通吹響號角,... 更多>
30年期國債期貨即將上市 首批3個合約將于4月21日交易
具體而言,中金所在《通知》中稱,30年期國債期貨首批... 更多>
時訊:好奇和天真
$東阿阿膠(SZ000423)$自己的簽名檔從來到雪球就是這個... 更多>