/** * Project Name:demo-project-generator * File Name:RedisLockBase.java * Package Name:com.gomeplus.market * Date:2017年8月7日上午10:16:23 * Copyright (c) 2017, suchao@gomeplus.com All Rights Reserved. * */ package cn.com.gome.game.rocket.client.base; import java.util.Date; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import redis.Gcache; /** * ClassName:RedisLockBase <br/> * Function: TODO ADD FUNCTION. <br/> * Reason: TODO ADD REASON. <br/> * Date: 2017年8月7日 上午10:16:23 <br/> * @author suchao * @version * @since JDK 1.8 * @see */ public abstract class RedisLockBase { /** * 日誌組件 */ private static final Logger logger = LoggerFactory.getLogger(RedisLockBase.class); /** * 等待超時時間 */ private long timeout = 12000L; /** * 等待線程休眠時間 */ private long threadSleep = 20L; /** * 鎖的有效時間 */ private long expire = 8000L; private Gcache cache = null; /** * 放開獲取redis測權限 * @Title: getCache * @Description: TODO * @param @return * @return Gcache * @throws */ public Gcache getCache() { return this.cache; } private String timeLock = ""; /** * * <p>Title: </p> * <p>Description: </p> * @param cache * @param timeLock */ public RedisLockBase(Gcache cache,String timeLock) { this.cache = cache; this.timeLock = timeLock; logger.debug("執行默認配置信息,lock:{},鎖保持時間:{},獲取鎖的等待時間:{},獲取等待休眠時間:{}",timeLock,String.valueOf(expire),String.valueOf(timeout),String.valueOf(threadSleep)); } /** * * <p>Title: </p> * <p>Description: </p> * @param cache * @param timeLock * @param timeout * @param threadSleep * @param expire */ public RedisLockBase(Gcache cache,String timeLock,long timeout,long threadSleep,long expire) { this.cache = cache; this.timeLock = timeLock; this.timeout = timeout; this.threadSleep = threadSleep; this.expire = expire; logger.debug("執行默認配置信息,lock:{},鎖保持時間:{},獲取鎖的等待時間:{},獲取等待休眠時間:{}",timeLock,String.valueOf(expire),String.valueOf(timeout),String.valueOf(threadSleep)); } /** * 執行加鎖事件 * @Title: excuteTask * @Description: TODO * @param @param cache * @param @param timeLock * @param @throws InterruptedException * @return void * @throws */ public void excuteTask() throws InterruptedException { logger.info("執行鎖定任務的緩存信息,lock:{},開始執行",timeLock); //執行 GOROOT:for(;true;){ //獲取鎖 String locktime = cache.get(timeLock); if(locktime==null || locktime.equals("")) { logger.debug("執行鎖定任務的緩存信息,lock:{},獲取redis鎖爲空,進行加鎖。",timeLock); //設置本身的鎖時間 long lockSelf = new Date().getTime() + expire; //設置鎖 Long lg = cache.setnx(timeLock , String.valueOf(lockSelf)); if(lg.longValue()>0) { //成功 logger.debug("執行鎖定任務的緩存信息,lock:{},獲取redis鎖成功,setnx返回結果:{}",timeLock,Long.toString(lg)); //操做數據 funAction(); //獲取時間 String time = cache.get(timeLock); long nowTime = new Date().getTime(); if(time!= null && !time.equals("") && new Long(time).longValue()> nowTime && String.valueOf(lockSelf).equals(time)) { //釋放鎖--會把別人的鎖刪除掉 cache.expire(timeLock, -1); logger.debug("執行鎖定任務的緩存信息,lock:{},獲取redis鎖成功,鎖時間:{},當前時間:{},清除當前鎖的LOCKKEY",timeLock,time,Long.toString(nowTime)); } logger.debug("執行鎖定任務的緩存信息,lock:{},獲取redis鎖成功,鎖時間:{},當前時間:{}",timeLock,time,Long.toString(nowTime)); }else { long timeouta = 0L; do { timeouta += threadSleep; //獲取時間 String time = cache.get(timeLock); long nowTime = new Date().getTime(); if(time==null || time.equals("") || new Long(time).longValue() < nowTime) { //超出了緩存時間 //釋放鎖 cache.expire(timeLock, -1); logger.debug("執行鎖定任務的緩存信息,lock:{},獲取redis鎖失敗,等待鎖釋放超時-清除鎖,鎖時間:{},當前時間:{}。",timeLock,time,Long.toString(nowTime)); continue GOROOT; } Thread.sleep(threadSleep); }while(timeouta<timeout); logger.debug("執行鎖定任務的緩存信息,lock:{},獲取redis鎖失敗,等待鎖超時,執行超時事件。",timeLock); //等待超時 funTimeout(); } }else { //鎖存在 logger.debug("執行鎖定任務的緩存信息,lock:{},獲取redis鎖存在,等待鎖釋放。",timeLock); long timeouta = 0L; do { timeouta += threadSleep; //獲取時間 String time = cache.get(timeLock); long nowTime = new Date().getTime(); if(time==null || time.equals("") || new Long(time).longValue() < nowTime) { //超出了緩存時間 logger.debug("執行鎖定任務的緩存信息,lock:{},redis鎖存在-等待鎖釋放超時-清除鎖,鎖時間:{},當前時間:{}",timeLock,time,Long.toString(nowTime)); //釋放鎖 cache.expire(timeLock, -1); continue GOROOT; } Thread.sleep(threadSleep); }while(timeouta<timeout); logger.debug("執行鎖定任務的緩存信息,lock:{},獲取redis鎖失敗,等待鎖超時,執行超時事件。",timeLock); //等待超時 funTimeout(); } //跳出整個循環 break; } logger.info("執行鎖定任務的緩存信息,lock:{},執行結束。",timeLock); } /** * 超時方法 * @Title: funTimeout * @Description: TODO * @param * @return void * @throws */ protected abstract void funTimeout(); /** * 鎖定處理事件 * @Title: funAction * @Description: TODO * @param * @return void * @throws */ protected abstract void funAction(); }