复制代码代码如下:
Package com.happyelements.odin.util;
import static com.google.common.base.precondition.Checknotnull;
import org.jetbrains.annotations.notnull;
import com.happyelements.odin.jedis.JeDisclient;
import com.happyelements.rdcenter.commons.util.datetimeutil;
/ **
* Utilisateur: Jude.wang
* Date: 14-1-16
* Heure: 上午 9:43
* /
classe publique concurrentUtil {
public static final String user_lock_key_format = "user_lock_% d_% s";
Public static final String Custom_lock_format = "Custom_lock_% s";
Redislient Jedisclient final statique publique = jedisclient.getInstance ();
Public Static Final String Unlocked = "0";
Public Static Final String Locked = "1";
Final statique privé int max_repeat_times = 10;
@Notnull
Public Static String buildUserLockKey (Long UserId, @notnull String Key) {
checkNotNull (clé);
return string.format (user_lock_key_format, userId, key);
}
@Notnull
public static string buildCustomLockKey (@notnull String key) {
checkNotNull (clé);
return string.format (personnalisé_lock_format, key);
}
/ **
* 此方法可以因为拿不到锁而导致 Opération 没有执行
*
* clé @param
* @see com.happyelements.odin.util.concurrentUtil # buildCustomlockKey (String)
* @see com.happyelements.odin.util.concurrentUtil # BuildUserLockkey (Long, String)
*
* Opération @param
* @throws com.happyelements.odin.util.concurrentutil.OperationNotexECException
* Opération 没有被执行
* /
public static void dojobwithlock (@notnull String key, @notnull ilockoperation opération) lève OperationNotexException {
Boolean verrouillé = false;
essayer {
checkNotNull (clé);
checknotnull (opération);
Locked = Lock (touche);
} catch (t) {
Jetez un nouveau OperationNoteXeCException (Key, T);
}
essayer {
if (verrouillé) {
// System.out.println (Thread.currentThread () + "/ T" + "Lock");
Operation.DoJob ();
} autre {
lancer un nouveau OperationNoteXeCException (clé);
}
} enfin {
if (verrouillé) {
déverrouiller (clé);
}
}
}
Déverrouillage de void statique privé (clé de chaîne) {
essayer {
checkNotNull (clé);
String OldStatus = Redislient.getSet (Key, déverrouillé);
if (isunlocked (oldstatus)) {
// Lock-> dojob-> 过期 -> déverrouiller
// Journal TODO
}
} catch (t) {
// Journal TODO
}
// System.out.println (Thread.currentThread () + "/ T" + "Unlock");
}
booléen statique privé iSunlocked (statut de chaîne) {
Retour status == null || status.equals (déverrouillé);
}
Lock booléen statique privé (clé de chaîne) {
Boolean verrouillé = false;
pour (int i = 0; i <max_repeat_times; i ++) {
String OldStatus = Redislient.getSet (clé, verrouillé);
if (isunlocked (oldstatus)) {
if (oldstatus == null) {
Redislient.Expire (Key, DateTimeUtil.Minute_Second * 5);
verrouillé = true;
casser;
}
verrouillé = true;
casser;
}
}
retour verrouillé;
}
Interface statique publique Ilockoperation {
void dojob ();
}
/ **
* {@link com.happyelements.odin.util.concurrentutil.ilockoperation # dojob ()} 没有被执行
* 上层必须处理该异常 , 捕获到该异常可以 Retry 本次操作 , 或者包装成 {@link com.happyelements.rdcenter.commons.throwable.heexception} 抛出去
* /
classe statique publique Operation NotexECException étend une exception {
Opération publiqueNotexECException () {
}
Opération publiqueNotexECException (String S) {
super (s);
}
Opération publiqueNotexECException (String S, jetable lancable) {
Super (s, jetable);
}
Opération Opération NotexECException (jetable jetable) {
Super (jetable);
}
}
}