redis分佈式鎖實現

用到的基本redis命令 setnx getset get 新手請自行腦補各個命令
實現步驟
ps:lockname 代表鎖名稱 time是代表 時間戳
1、setnx lockname time1
客戶端c1嘗試獲取鎖,返回1 則c1成功獲取鎖 可以進行操作 返回0 則表示獲取鎖失敗 進入下一步
2、 get lockname
獲取時間戳 t1 判斷時間是否過期 (防止死鎖)
過期? 否:結束等待下次運行 是:轉3
3、 getset lockname time2
獲取舊的時間 oldTime2 和第二步的時間進行比較,如果相等說明 已經成功獲取了鎖,如果不相等說明被別的客戶端捷足先登了。進入等待狀態。

源碼示例:`
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import redis.clients.jedis.Jedis;
import redis.clients.util.Pool;

public class JobUtil {
private static Logger logger = LoggerFactory.getLogger(JobUtil.class);
public static void main(String[] args) {
String str = “2016-09-01 13:16:30:125”;
Date date = null;
SimpleDateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss:SSS”);//,”2016-09-01 12:36:30”);;
try {
date = sdf.parse(str);
System.out.println(” 1::: “+date.getTime());
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// checkWhetherCanGetLock(date.getTime()+”“,null);

}

public static boolean checkWhetherCanGetLock(String THREAD_LOCK,Jedis jedis,Integer expireSeconds){
try{
expireSeconds =expireSeconds==null ? 60*3 : expireSeconds;
long result = jedis.setnx(THREAD_LOCK, String.valueOf(new Date().getTime()));
if(result==1){ //get the lock
return true;
}else{
String timeStr = jedis.get(THREAD_LOCK);
long originTime = Long.parseLong(timeStr);
long nowTime = new Date().getTime();
if(Math.abs(nowTime-originTime)>expireSeconds*1000){//has already expire
String oldTimeStr = jedis.getSet(THREAD_LOCK, String.valueOf(new Date().getTime()));
if(StringUtils.isNotBlank(oldTimeStr)){ //check whether it is expire or not
long oldTime = Long.parseLong(oldTimeStr);
if(originTime==oldTime){
return true;
}else{
return false;
}
}else{//execute the job
return true;
}
}else{
return false;
}
}

}catch(Exception e){
e.printStackTrace();
logger.error(“判斷是否獲取鎖失敗!”);
return true;
}
}
}
`
本人這個是用於防止定時任務重複執行的,如果讀者想用於處理其他的併發問題請自行封裝。。。
有任何問題,歡迎直接回復或加QQ羣:282034885討論。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章