Package com.happyelements.odin.util;
Import static com.google.common.base.Preconditions.checkNotNull;
Import Org.jetbrains.annotations.NotNull;
Import com.happyelements.odin.jedis.JedisClient;
Import Com.happyelements.rdcenter.commons.util.DateTimeUtil;
/**
* User:jude.wang
* date:14-1-16
* Time: 9:43
*/
public class Concurrentutil {
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 unlocked = "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);
}
/**
* This method can cause the operation not to be executed because the lock is not taken
*
* @param key
* @see Com.happyelements.odin.util.concurrentutil#buildcustomlockkey (String)
* @see Com.happyelements.odin.util.concurrentutil#builduserlockkey (long, String)
*
* @param operation
* @throws com.happyelements.odin.util.ConcurrentUtil.OperationNotExecException
* Operation not been executed
*/
public static void Dojobwithlock (@NotNull String key, @NotNull ilockoperation operation) throws operationnotexecexception {
Boolean locked = FALSE;
try {
Checknotnull (key);
Checknotnull (operation);
Locked = lock (key);
catch (Throwable t) {
throw new Operationnotexecexception (key, T);
}
try {
if (locked) {
//System.out.println ( Thread.CurrentThread () + "T" + "lock");
operation.dojob ();
} else {
throw new operationnotexecexception (key);
  &NBSP}
} finally {
if (locked) {
Unlock (key);
}
}
}
private static void Unlock (String key) {
try {
Checknotnull (key);
String oldstatus = Redisclient.getset (key, unlocked);
if (isunlocked (Oldstatus)) {
Lock->dojob-> Expired->unlock
TODO LOG
}
catch (Throwable t) {
TODO LOG
}
System.out.println (Thread.CurrentThread () + "T" + "unlock");
}
private static Boolean isunlocked (String status) {
return status = NULL | | Status.equals (unlocked);
}
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;
Break
}
Locked = true;
Break
}
}
return locked;
}
public static interface Ilockoperation {
void Dojob ();
}
/**
* {@link com.happyelements.odin.util.concurrentutil.ilockoperation#dojob ()} was not executed
* The upper layer must handle the exception, catch the exception can be retry this operation, or wrapped into {@link com.happyelements.rdcenter.commons.throwable.HeException} thrown out
*/
public static class Operationnotexecexception extends Exception {
Public Operationnotexecexception () {
}
Public Operationnotexecexception (String s) {
Super (s);
}
Public Operationnotexecexception (String s, throwable throwable) {
Super (S, throwable);
}
Public operationnotexecexception (Throwable throwable) {
Super (Throwable);
}
}
}