复制代码代码如下:
パッケージcom.happyelements.odin.util;
static com.google.common.base.preconditions.checknotnullをインポートします。
import org.jetbrains.annotations.notnull;
com.happyelements.odin.jedis.jedisclientをインポートします。
com.happyelements.rdcenter.commons.util.datetimeutilをインポートします。
/**
*ユーザー:Jude.Wang
*日付:14-1-16
*時間:上午9:43
*/
パブリッククラスの同意{
public static final string user_lock_key_format = "user_lock_%d_%s";
public static final string custom_lock_format = "custom_lock_%s";
public static final jedisclient redisclient = jedisclient.getInstance();
public static final string locked = "0";
public static final string locked = "1";
Private Static Final int max_repeat_times = 10;
@notnull
public static string builduserlockkey(long userid、@notnull string key){
checknotnull(key);
return string.format(user_lock_key_format、userid、key);
}
@notnull
public static string buildcustomlockkey(@notnull string key){
checknotnull(key);
return string.format(custom_lock_format、key);
}
/**
*此方法可以因为拿不到锁而导致操作没有执行
*
* @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.operationnotexexcection
*操作没有被执行
*/
public static void dojobwithlock(@notnull string key、@notnull ilockoperation操作)operationnotexexception {
boolean locked = false;
試す {
checknotnull(key);
checknotnull(操作);
locked = lock(key);
} catch(スロー可能なt){
新しいOperationNotexecexception(key、t);
}
試す {
if(locked){
// system.out.println(thread.currentthread() + "/t" + "lock");
Operation.Dojob();
} それ以外 {
新しいOperationNotexecexception(key);
}
} ついに {
if(locked){
ロック解除(key);
}
}
}
private static void lock(string key){
試す {
checknotnull(key);
string oldstatus = redisclient.getset(key、locked);
if(isunlocked(oldstatus)){
// lock-> dojob->过期 - >ロックを解除します
// todo log
}
} catch(スロー可能なt){
// todo log
}
// system.out.println(thread.currentthread() + "/t" + "lock");
}
private static boolean isunlocked(string status){
return status == null || status.equals(ロック解除);
}
Private Static Boolean Lock(String Key){
boolean locked = false;
for(int i = 0; i <max_repeat_times; i ++){
string oldstatus = redisclient.getset(key、locked);
if(isunlocked(oldstatus)){
if(oldstatus == null){
redisclient.expire(key、datetimeutil.minute_second * 5);
locked = true;
壊す;
}
locked = true;
壊す;
}
}
ロックされた返品;
}
public static interface ilockoperation {
void dojob();
}
/**
* {@link com.happyelements.odin.util.concurrentutil.ilockoperation#dojob()}}
*上层必须处理该异常、捕获到该异常可以retry本次操作、或者包装成{@link com.happyelements.rdcenter.commons.throwable.heexception}抛出去
*/
public static class operationnotexecexceptionは例外を拡張します{
puply operationNotexecexception(){
}
Pulily OperationNotexecexception(String S){
スーパー(s);
}
pulaly operationNotexecexception(String S、Throwable Throwable){
スーパー(s、スロー可能);
}
puply operationNotexecexception(スロー可能なスロー可能){
Super(Throwable);
}
}
}