【環(huán)球新視野】針對RedisTemplate分布式鎖實現(xiàn)WatchDog
2023-04-21 16:22:48
【資料圖】
在此之前,去看了下Redission的實現(xiàn)原理,不過在開發(fā)中,原本的代碼使用RedistTemplate實現(xiàn)的,也不太想換,所以我想了下,不如自己實現(xiàn)要給WatchDog。
我的想法是,在用戶加上鎖的時候開啟個定時任務(wù)線程,并且在定時任務(wù)中,判斷原線程isAlive狀態(tài)進行“續(xù)命”。
下面是代碼(在這里面為了方便,未使用的是HuTool.CornUtil來實現(xiàn)動態(tài)定時任務(wù)):
/** * Title * * @ClassName: LockUtil * @Description:鎖工具類,通過內(nèi)部枚舉類實現(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; /** * 帶看門狗機制上鎖 * @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); //實現(xiàn)看門狗 if (isDelay){ if (LockUtil.isOpenCorn==false){ //如果同一個項目之前打開過,那么先關(guān)閉,避免重復啟動 CronUtil.stop(); //支持秒級別定時任務(wù) CronUtil.setMatchSecond(true); //定時服務(wù)啟動 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); } //利用枚舉類實現(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; }}
標簽:
- 【環(huán)球新視野】針對RedisTemplate分布式鎖實現(xiàn)WatchDog
- 全球觀速訊丨成都軌道交通7號線工程獲中國土木工程“詹天佑獎”
- 什么是牛胸??? 每日快訊
- 全球要聞:4月21日原油市場行情:油價繼續(xù)下跌向缺口靠近
- 餐(飲)具消毒“碼”上見
一鍵溯源讓百姓用上放心碗筷 - 【環(huán)球新視野】宏碁發(fā)布全新傳奇Go 16,銳龍7000+RTX40打造更強生產(chǎn)力!
- 上海土拍戰(zhàn)況激烈:已成交410億,建發(fā)未如愿,華發(fā)中獎明星地塊
- 丹鳳縣氣象臺發(fā)布雷雨大風黃色預(yù)警【Ⅲ級/較重】 全球最資訊
- 【速看料】十八少年話涼州
- 長峰醫(yī)院火災(zāi)事故原因:施工過程中火花引燃揮發(fā)物
- 59+11!53+13!杜蘭特力挺你,哈登果然兌現(xiàn)承諾,幫你完成大滿貫
- 興力工程公司聯(lián)合鑫順產(chǎn)業(yè)集團開展紀委委員聯(lián)學活動 視點
- 【天天播資訊】第一種形態(tài)十四種方式有哪些_第一種形態(tài)十四種方式
- 創(chuàng)新鄉(xiāng)村旅游業(yè)態(tài) 蘇州多個產(chǎn)品和項目入選“省級示范”|今日要聞
- 電腦制圖入門教程_怎樣在電腦上設(shè)計制圖
- “對飆局”兩人砍下40+,穆雷助掘金再勝森林狼_世界新動態(tài)
- 本賽季歐冠克羅斯觸球傳球次數(shù)均領(lǐng)跑,傳球成功率94% 天天新資訊
- 觀察:今天最新消息 太湖平均水位3.07米 為近20年同期最低
- 每日動態(tài)!古特雷斯呼吁蘇丹沖突各方?;鹑?/a>
- 天天消息!京郊度假酒店“五一”降溫
- AC米蘭上一次成為歐冠四強時,世界是這樣的……
- 特斯拉起訴前工程師盜取超算機密,最終雙方和解
- 【焦點熱聞】天水市委依法治市辦對秦安縣開展專項監(jiān)督檢查
- 焦點熱訊:解元會元狀元連中三元是什么意思_解元會元狀元
- 環(huán)球熱推薦:長沙4宗熔斷地塊搖號名單出爐!將于4月25日定主
- 全省第一!濟南高新區(qū)29個人工智能應(yīng)用場景入選省級名單
- ST目藥2022年業(yè)績預(yù)告更正:預(yù)計虧損6500萬元-7200萬元
- 調(diào)查顯示:中國內(nèi)地小微企業(yè)料現(xiàn)穩(wěn)健復蘇
- 蟲草花是什么東西長出來的_蟲草花是什么|世界微資訊
- 益客食品(301116.SZ)發(fā)2022年度業(yè)績,凈利潤5174.36萬元,同比減少55.83%,每10股派0.5元
x
廣告
- 韓國電信公布未來五年非基礎(chǔ)設(shè)施投資預(yù)算撥出12萬億韓元
- 冰墩墩設(shè)計者給北京四中學生回信:祝??蓯蹔^進的中國少
- 江蘇南通發(fā)現(xiàn)1人檢測結(jié)果呈陽性 系外地返通人員
- 湖南郴州報告2例香港返湘人員新冠肺炎確診病例
- 廣西百色疫情社區(qū)傳播鏈基本阻斷
- 廣西新增1例本土確診病例 本輪本土疫情累計報告確診病例
- 葫蘆島市兩醫(yī)院不再收治非綏中地區(qū)患者 就醫(yī)患者閉環(huán)管理
- 蘇州14日新增本土確診1例,無癥狀感染者3例 詳情及軌跡公布
- 2021年北京空氣質(zhì)量創(chuàng)歷史最優(yōu) 首次全面達標
- 化屋村火起來了
- 國家藥監(jiān)局:“小金盾”不是質(zhì)量認證標志
- 大霧!湖南18條高速通行受影響 157個收費站臨時交通管制
x
廣告