复制代码代码如下:
пакет com.happyelements.odin.util;
Импорт static com.google.common.base.preconditions.checknotnull;
Импорт org.jetbrains.annotation.notnull;
Импорт com.happyelements.odin.jedis.jedisclient;
Import com.happyelements.rdcenter.commons.util.datetimeutil;
/**
* Пользователь: Jude.wang
* Дата: 14-1-16
* Время: 上午 9:43
*/
открытый класс coundrentutil {
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 Resisclient = jedisclient.getInstance ();
Общественная статическая конечная строка разблокирована = "0";
публичная статическая конечная строка Locked = "1";
Private Static Final int max_repeat_times = 10;
@Notnull
Public Static String BulderSerLockkey (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 Key
* @see com.happyelements.odin.util.concurrentutil#buildcustomlockkey (String)
* @see com.happyelements.odin.util.concurrentutil#builduserlockkey (long, string)
*
* @param операция
* @Throws com.happyElments.odin.util.concurrentutil.operationnotexecexception
* Операция 没有被执行
*/
Public Static void Dojobwithlock (@notnull String Key, @notnull ilockoperation Operation)
логический заблокирован = false;
пытаться {
CheckNotnull (Key);
CheckNotnull (операция);
Locked = lock (ключ);
} catch (throwable t) {
бросить новую OperationNotexeCexception (Key, T);
}
пытаться {
if (заблокировано) {
// System.out.println (think.currentThread () + "/t" + "lock");
Operation.dojob ();
} еще {
бросить новую OperationNotexeCexception (Key);
}
} окончательно {
if (заблокировано) {
разблокировать (ключ);
}
}
}
private static void разблокировка (String Key) {
пытаться {
checknotnull (ключ);
String oldstatus = redisclient.getset (ключ, разблокирован);
if (isuncloded (oldstatus)) {
// lock-> dojob-> 过期-> Разблокировать
// todo log
}
} catch (throwable t) {
// todo log
}
// System.out.println (think.currentThread () + "/t" + "разблокировать");
}
Private Static Boolean Isunclocked (String Status) {
Статус возврата == null || status.equals (разблокирован);
}
Private Static Boolean Lock (String Key) {
логический заблокирован = false;
для (int i = 0; i <max_repeat_times; i ++) {
String oldstatus = redisclient.getset (ключ, заблокирован);
if (isuncloded (oldstatus)) {
if (oldstatus == null) {
redisclient.expire (key, datetimeutil.minute_second * 5);
Locked = true;
перерыв;
}
Locked = true;
перерыв;
}
}
вернуть заблокирован;
}
публичный статический интерфейс ilockoperation {
void dojob ();
}
/**
* {@link com.happyelements.odin.util.concurrentutil.ilockoperation#dojob ()} 没有被执行
* 上层必须处理该异常 , 捕获到该异常可以 повторение 本次操作 , 或者包装成 {@link com.happyelements.rdcenter.commons.throwable.heexception} 抛出去
*/
Public Static Class OperationNotexeCexception расширяет исключение {
public operationnotexecexception () {
}
Public OperationNotexeCexception (String S) {
супер (ы);
}
Public OperationNotexeCexception (String S, бросаемый бросок) {
Super (s, бросаемый);
}
Public OperationNotexeCexception (бросание, бросаемое) {
супер (бросаемый);
}
}
}