位置: 首頁 >> 資訊 > > 正文

          針對RedisTemplate分布式鎖實現WatchDog_全球資訊

          2023-04-21 12:41:09 來源:騰訊云


          (相關資料圖)

          在此之前,去看了下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;        }}

          標簽:

          上一篇:快看點丨4月28日截止!云南這項創業企業獎補申報正在進行
          下一篇:最后一頁
          亚洲欧洲国产综合| 久久亚洲AV成人无码电影| 亚洲成人福利网站| 久久精品亚洲日本佐佐木明希| 亚洲日本va午夜中文字幕久久| 久久水蜜桃亚洲AV无码精品| 亚洲熟伦熟女专区hd高清| 亚洲偷自精品三十六区| 亚洲人成激情在线播放| 亚洲二区在线视频| 亚洲日本va在线观看| 国产v亚洲v天堂a无| 国产亚洲中文日本不卡二区| 亚洲永久在线观看| 亚洲中文字幕无码久久| 亚洲综合激情五月色一区| 中文字幕亚洲码在线| 亚洲人成人伊人成综合网无码| 亚洲日韩精品无码专区| 亚洲乱色熟女一区二区三区蜜臀| 亚洲欧美日韩自偷自拍| 久久亚洲精品无码网站| 亚洲Av无码乱码在线观看性色| 亚洲精品国产精品乱码不卞| 国产a v无码专区亚洲av| 在线a亚洲v天堂网2019无码| 亚洲精品无码高潮喷水在线| 久久精品国产亚洲一区二区| 亚洲第一成年男人的天堂| 亚洲精彩视频在线观看| 亚洲剧情在线观看| 亚洲日本一线产区和二线产区对比| 亚洲男人天堂2018av| 亚洲AV女人18毛片水真多| 亚洲国产综合精品一区在线播放| 中文字幕中韩乱码亚洲大片| 亚洲gv猛男gv无码男同短文| 亚洲熟伦熟女专区hd高清| 亚洲欧美成人av在线观看| 亚洲国产综合久久天堂| 亚洲精品国产精品乱码不99|