/**
* 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();
}