复制代码代码如下:
paquete com.happyelements.odin.util;
Importar static com.google.common.base.preconditions.checknotnull;
importar org.jetbrains.annotations.notnull;
import com.happyelements.odin.jedis.jedisclient;
import com.happyelements.rdcenter.commons.util.datetimeutil;
/**
* Usuario: Jude.wang
* Fecha: 14-1-16
* Hora: 上午 9:43
*/
clase pública concurrente {
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 desbloqueado = "0";
Cadena final estática pública bloqueada = "1";
Private estático final int max_repeat_times = 10;
@Notnull
public static string buildUserLockKey (Long UserId, @NotNnull String Key) {
checkNotNull (clave);
return string.format (user_lock_key_format, userId, key);
}
@Notnull
public static String buildCustomLockKey (@NotNnull String Key) {
checkNotNull (clave);
return string.format (custom_lock_format, key);
}
/**
* 此方法可以因为拿不到锁而导致 Operación 没有执行
*
* @Param Key
* @see com.happyelements.odin.util.concurrentutil#buildCustomLockKey (cadena)
* @see com.happyelements.odin.util.concurrentutil#builduserlockkey (largo, cadena)
*
* @Param Operation
* @throws com.happyelements.odin.util.concurrentutil.operationnotexecexception
* Operación 没有被执行
*/
public static void doJobwithlock (@NotNnull String Key, @notnull IlockOperation Operation) lanza OperationNotExecException {
booleano bloqueado = falso;
intentar {
checkNotNull (clave);
checkNotNull (operación);
bloqueado = bloqueo (tecla);
} Catch (Throwable t) {
arrojar una nueva operación NotExecException (Key, T);
}
intentar {
if (bloqueado) {
// system.out.println (thread.currentThread () + "/t" + "bloqueo");
operation.doJob ();
} demás {
tirar una nueva operación NotExecException (clave);
}
} finalmente {
if (bloqueado) {
desbloquear (clave);
}
}
}
desbloqueo vacío estático privado (tecla de cadena) {
intentar {
checkNotNull (clave);
Cadena OldStatus = RedIsClient.GetSet (clave, desbloqueado);
if (isunlocked (OldStatus)) {
// bloqueo-> doJob-> 过期-> desbloquear
// TODO LOG
}
} Catch (Throwable t) {
// TODO LOG
}
// System.out.println (Thread.CurrentThread () + "/t" + "desbloquear");
}
ISUNLOCLED ISUNLOCLED BOOLEO ESTÁTICO PRIVADO (estado de cadena) {
Estado de retorno == NULL || status.equals (desbloqueado);
}
bloqueo booleano estático privado (tecla de cadena) {
booleano bloqueado = falso;
para (int i = 0; i <max_repeat_times; i ++) {
Cadena OldStatus = RedIsClient.GetSet (tecla, bloqueada);
if (isunlocked (OldStatus)) {
if (OldStatus == NULL) {
RedIsClient.EXPIRE (Key, DateTimeUtil.Minute_Second * 5);
bloqueado = verdadero;
romper;
}
bloqueado = verdadero;
romper;
}
}
regresar bloqueado;
}
interfaz estática pública ilockoperation {
nulo doJob ();
}
/**
* {@link com.happyelements.odin.util.concurrentutil.ilockoperation#dojob ()} 没有被执行
* 上层必须处理该异常 , 捕获到该异常可以 Retint 本次操作 , 或者包装成 {@link com.happyelements.rdcenter.commons.throwable.heexception} 抛出去
*/
Public Static ClasserNotExecException extiende la excepción {
Public OperationNotExecException () {
}
Public OperationNotExecException (String s) {
super (s);
}
Public OperationNotExecException (String S, Throwable Throwable) {
super (s, lanzable);
}
Public OperationNotExecException (Throwable Throwable) {
super (lanzable);
}
}
}