1、导包
<dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>3.14.1</version></dependency>
2、创建注解
package com.woniu.movie1.utils;import java.lang.annotation.*;@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface RidissonLock { String lockKey() default ""; //key值,自己设定 int time() default 20; //过期时间 int lockTimeOut() default 20; //超时时间 String start() default ""; //前缀 String end() default ""; //后缀 int index() default 0; //索引 String fielName() default ""; //字段名}
3、创建锁
package com.woniu.movie1.utils;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.reflect.MethodSignature;import org.redisson.api.RLock;import org.redisson.api.RedissonClient;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import java.lang.reflect.Method;import java.util.concurrent.TimeUnit;@Aspect @Componentpublic class LockAdvice { @Autowired private RedissonClient rc; //execution切入点表达式@annotatio锁绝对路径 @Around("execution(* *..service..*.*(..))&&@annotation(com.woniu.movie1.utils.RidissonLock)") public Object lock(ProceedingJoinPoint pjp){ RLock lock=null; try { MethodSignature ms=(MethodSignature) pjp.getSignature(); Method method = ms.getMethod(); RidissonLock rl = method.getDeclaredAnnotation(RidissonLock.class); String className = pjp.getTarget().getClass().getName();//类的绝对路径 String methodName = pjp.getSignature().getName(); //方法名 lock = rc.getLock(className+":"+methodName); boolean b = lock.tryLock( rl.time(),rl.lockTimeOut(),TimeUnit.SECONDS); if(b){ return pjp.proceed();//上锁成功 } }catch (Throwable e){ e.printStackTrace(); throw new RuntimeException(e);//出现异常 }finally { lock.unlock();//解锁 } return null; }}
4、注解上锁
package com.woniu.movie1.service.impl;
import com.woniu.movie1.utils.RidissonLock;
import com.woniu.movie1.utils.UtilLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class TestLockService {
@Resource
private StringRedisTemplate srt;
//@RidissonLock(lockKey="abc")
@RidissonLock
public void addI(){
System.out.println("进入了");
Integer i=Integer.parseInt(srt.opsForValue().get("i"));
if(i<2000){
i++;
srt.opsForValue().set("i",i+"");
}
}
}
5、测试
package com.woniu.movie1.controller;
import org.springframework.web.client.RestTemplate;
import java.util.Random;
public class TestLock {
public static class Thread1 extends Thread{
@Override
public void run() {
RestTemplate restTemplate=new RestTemplate();
for (int i = 0; i < 200; i++) {
int s = new Random().nextInt(2);
System.out.println(s);
if(s==1){
restTemplate.getForObject("http://localhost:8888/movie1/addI",String.class);
}else {
restTemplate.getForObject("http://localhost:9999/movie1/addI",String.class);
}
}
}
}
public static void main(String[] args) {
System.out.println("执行了mian");
Thread1 t1=new Thread1();
t1.start();
Thread1 t2=new Thread1();
t2.start();
}
}