注解方式優(yōu)雅的實(shí)現(xiàn) Redisson 分布式鎖
閱讀本文大概需要 4 分鐘。
來(lái)自:juejin.cn/post/7215142807861379109
1前言
2Redisson分布式鎖常規(guī)使用
Lock
public void getLock(){
//獲取鎖
RLock lock = redisson.getLock("Lxlxxx_Lock");
try {
// 2.加鎖
lock.lock();
} catch (InterruptedException e) {
e.getStackTrace();
} finally {
// 3.解鎖
lock.unlock();
System.out.println("Finally,釋放鎖成功");
}
TryLock
RLock lock = redisson.getLock(name);
try {
if (lock.tryLock(2, 10, TimeUnit.SECONDS)) {
//執(zhí)行業(yè)務(wù)邏輯
} else {
System.out.println("已存在");
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
//判斷當(dāng)前線程持有的鎖是不是處于鎖定狀態(tài),鎖定狀態(tài)再進(jìn)行釋放
if (this.redissonLock.isHeldByCurrentThread(lockName)) {
this.redissonLock.unlock(lockName);
}
}
3自定義注解實(shí)現(xiàn)鎖機(jī)制
自定義注解
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface DistributedLock {
String key() default "";
int leaseTime() default 10;
boolean autoRelease() default true;
String errorDesc() default "系統(tǒng)正常處理,請(qǐng)稍后提交";
int waitTime() default 1;
}
切面類(lèi)實(shí)現(xiàn)
@Aspect
@Component
public class DistributedLockHandler {
private static final Logger log = LoggerFactory.getLogger(DistributedLockHandler.class);
@Autowired
RedissonLock redissonLock;
public DistributedLockHandler() {
}
@Around("@annotation(distributedLock)")
public Object around(ProceedingJoinPoint joinPoint, DistributedLock distributedLock) throws Throwable {
String lockName = this.getRedisKey(joinPoint, distributedLock);
int leaseTime = distributedLock.leaseTime();
String errorDesc = distributedLock.errorDesc();
int waitTime = distributedLock.waitTime();
Object var8;
try {
boolean lock = this.redissonLock.tryLock(lockName, (long)leaseTime, (long)waitTime);
if (!lock) {
throw new RuntimeException(errorDesc);
}
var8 = joinPoint.proceed();
} catch (Throwable var12) {
log.error("執(zhí)行業(yè)務(wù)方法異常", var12);
throw var12;
} finally {
if (this.redissonLock.isHeldByCurrentThread(lockName)) {
this.redissonLock.unlock(lockName);
}
}
return var8;
}
/**
* 獲取加鎖的key
* @param joinPoint
* @param distributedLock
* @return
*/
private String getRedisKey(ProceedingJoinPoint joinPoint, DistributedLock distributedLock) {
String key = distributedLock.key();
Object[] parameterValues = joinPoint.getArgs();
MethodSignature signature = (MethodSignature)joinPoint.getSignature();
Method method = signature.getMethod();
DefaultParameterNameDiscoverer nameDiscoverer = new DefaultParameterNameDiscoverer();
String[] parameterNames = nameDiscoverer.getParameterNames(method);
if (StringUtils.isEmpty(key)) {
if (parameterNames != null && parameterNames.length > 0) {
StringBuffer sb = new StringBuffer();
int i = 0;
for(int len = parameterNames.length; i < len; ++i) {
sb.append(parameterNames[i]).append(" = ").append(parameterValues[i]);
}
key = sb.toString();
} else {
key = "redissionLock";
}
return key;
} else {
SpelExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression(key);
if (parameterNames != null && parameterNames.length != 0) {
EvaluationContext evaluationContext = new StandardEvaluationContext();
for(int i = 0; i < parameterNames.length; ++i) {
evaluationContext.setVariable(parameterNames[i], parameterValues[i]);
}
try {
Object expressionValue = expression.getValue(evaluationContext);
return expressionValue != null && !"".equals(expressionValue.toString()) ? expressionValue.toString() : key;
} catch (Exception var13) {
return key;
}
} else {
return key;
}
}
}
}
具體使用
4總結(jié)
推薦閱讀:
面試官:如何使用 Dockerfile 去構(gòu)建自定義的 Docker 鏡像?問(wèn)倒一大片.....
在國(guó)企和央企當(dāng)程序員體驗(yàn),太真實(shí)了。。
互聯(lián)網(wǎng)初中高級(jí)大廠面試題(9個(gè)G) 內(nèi)容包含Java基礎(chǔ)、JavaWeb、MySQL性能優(yōu)化、JVM、鎖、百萬(wàn)并發(fā)、消息隊(duì)列、高性能緩存、反射、Spring全家桶原理、微服務(wù)、Zookeeper......等技術(shù)棧!
?戳閱讀原文領(lǐng)取! 朕已閱

