redis實(shí)現(xiàn)多進(jìn)程數(shù)據(jù)同步工具代碼分享
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);
}
/**
* 此方法可以因?yàn)槟貌坏芥i而導(dǎo)致operation沒(méi)有執(zhí)行
*
* @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沒(méi)有被執(zhí)行
*/
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);
}
} 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->過(guò)期->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()}沒(méi)有被執(zhí)行
* 上層必須處理該異常,捕獲到該異??梢詒etry本次操作,或者包裝成{@link com.happyelements.rdcenter.commons.throwable.HeException} 拋出去
*/
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);
}
}
}
相關(guān)文章
java組裝樹(shù)形結(jié)構(gòu)List問(wèn)題
這篇文章主要介紹了java組裝樹(shù)形結(jié)構(gòu)List問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08
Java之SpringCloud Eurka注冊(cè)錯(cuò)誤解決方案
這篇文章主要介紹了Java之SpringCloud Eurka注冊(cè)錯(cuò)誤解決方案,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
Java調(diào)用參數(shù)類(lèi)型是application/x-www-form-urlencoded的API問(wèn)題
在使用Postman進(jìn)行接口測(cè)試時(shí),對(duì)于POST請(qǐng)求,需將請(qǐng)求頭設(shè)置為application/x-www-form-urlencoded,并將參數(shù)轉(zhuǎn)為String類(lèi)型,通常在GET請(qǐng)求中,參數(shù)直接拼接在URL后,本文通過(guò)具體實(shí)例,詳細(xì)講解了參數(shù)處理的方法,適合API開(kāi)發(fā)者參考2024-09-09
Java開(kāi)發(fā)必備知識(shí)之?dāng)?shù)組詳解
數(shù)組對(duì)于每一門(mén)編程語(yǔ)言來(lái)說(shuō)都是重要的數(shù)據(jù)結(jié)構(gòu)之一,當(dāng)然不同語(yǔ)言對(duì)數(shù)組的實(shí)現(xiàn)及處理也不盡相同.本篇文章為大家整理了Java最全關(guān)于數(shù)組的知識(shí)點(diǎn),并給出其對(duì)應(yīng)的代碼,需要的朋友可以參考下2021-06-06
詳解Java集合中的基本數(shù)據(jù)結(jié)構(gòu)
總有小伙伴讓我總結(jié)一下Java集合中的基本數(shù)據(jù)結(jié)構(gòu)的相關(guān)知識(shí),今天特地整理了本篇文章,文中有非常詳細(xì)的介紹,需要的朋友可以參考下2021-06-06
Java利用位運(yùn)算實(shí)現(xiàn)比較兩個(gè)數(shù)的大小
這篇文章主要為大家介紹了,在Java中如何不用任何比較判斷符(>,==,<),返回兩個(gè)數(shù)( 32 位整數(shù))中較大的數(shù),感興趣的可以了解一下2022-08-08

