複製代碼代碼如下:
包com.happylements.odin.util;
導入靜態com.google.common.base.base.preconditions.checknotnull;
導入org.jetbrains.annotations.notnull;
導入com.happyelements.odin.jedis.jedisclient;
導入com.happyelements.rdcenter.commons.util.datetimeutil;
/**
*用戶:Jude.Wang
*日期:14-1-16
*時間:上午9:43
*/
公共類Concurrentutil {
公共靜態最終字符串user_lock_key_format =“ user_lock_%d_%s”;
公共靜態最終字符串custom_lock_format =“ custom_lock_%s”;
公共靜態最終jedisclient redisclient = jedisclient.getInstance();
公共靜態最終字符串解鎖=“ 0”;
公共靜態最終字符串鎖定=“ 1”;
私有靜態最終int max_repeat_times = 10;
@notnull
public static String builduserlockkey(long userId,@notnull String鍵){
checknotnull(key);
return string.format(user_lock_key_format,userId,key);
}
@notnull
public static String buildcustomlockkey(@notnull String鍵){
checknotnull(key);
return string.format(custom_lock_format,鍵);
}
/**
*此方法可以因為拿不到鎖而導致操作沒有執行
*
* @param鍵
* @See com.happyelements.odin.util.concurrentutil#buildcustomlockkey(string)
* @See com.happyelements.odin.util.concurrentutil#builduserlockkey(long,string)
*
* @param操作
* @throws com.happyelements.odin.util.concurrentutil.operationnotexecexception
*操作沒有被執行
*/
public static void dojobwithlock(@notnull String鍵,@notnull iLockoperation操作)拋出操作notexecexception {
布爾鎖= false;
嘗試 {
checknotnull(key);
checknotnull(操作);
鎖定=鎖(鍵);
} catch(可投擲T){
投擲新操作NoteXecexception(key,t);
}
嘗試 {
如果(鎖定){
// system.out.println(thread.currentthread() +“/t” +“ lock”);
aperation.dojob();
} 別的 {
投擲新操作NoteXecexception(key);
}
} 最後 {
如果(鎖定){
解鎖(鍵);
}
}
}
私有靜態void解鎖(字符串鍵){
嘗試 {
checknotnull(key);
字符串oldstatus = redisclient.getSet(鍵,解鎖);
如果(isunlocked(oldstatus)){
// lock-> dojob-->過期->解鎖
// todo log
}
} catch(可投擲T){
// todo log
}
// system.out.println(thread.currentthread() +“/t” +“ unlock”);
}
私有靜態布爾值isunlocked(字符串狀態){
返回狀態== null ||狀態。平等(解鎖);
}
私有靜態布爾鎖(字符串鍵){
布爾鎖= false;
for(int i = 0; i <max_repeat_times; i ++){
字符串oldstatus = redisclient.getSet(鍵,鎖定);
如果(isunlocked(oldstatus)){
if(oldstatus == null){
redisclient.expire(鍵,dateTimeUtil.minute_second * 5);
鎖定= true;
休息;
}
鎖定= true;
休息;
}
}
返回鎖定;
}
公共靜態接口iLockoperation {
void dojob();
}
/**
* {@link com.happyelements.odin.util.concurrentutil.ilockoperation#dojob()}沒有被執行
*上層必須處理該異常,捕獲到該異常可以,重試,或者包裝成{@link com.happyelements.rdcenter.commons.throwable.heexception}拋出去
*/
公共靜態類操作notexecexception擴展了異常{
public OperationNoteXecexception(){
}
公共操作NoteXecexception(String s){
超級
}
公共操作NoteXecexception(字符串S,可拋出){
超級(S,可投擲);
}
公共操作NoteXecexception(可投擲){
超級(可投擲);
}
}
}