1、导包

  1. <dependency>
  2. <groupId>org.redisson</groupId>
  3. <artifactId>redisson-spring-boot-starter</artifactId>
  4. <version>3.14.1</version>
  5. </dependency>

2、创建注解

  1. package com.woniu.movie1.utils;
  2. import java.lang.annotation.*;
  3. @Target(ElementType.METHOD)
  4. @Retention(RetentionPolicy.RUNTIME)
  5. @Documented
  6. public @interface RidissonLock {
  7. String lockKey() default ""; //key值,自己设定
  8. int time() default 20; //过期时间
  9. int lockTimeOut() default 20; //超时时间
  10. String start() default ""; //前缀
  11. String end() default ""; //后缀
  12. int index() default 0; //索引
  13. String fielName() default ""; //字段名
  14. }

3、创建锁

  1. package com.woniu.movie1.utils;
  2. import org.aspectj.lang.ProceedingJoinPoint;
  3. import org.aspectj.lang.annotation.Around;
  4. import org.aspectj.lang.annotation.Aspect;
  5. import org.aspectj.lang.reflect.MethodSignature;
  6. import org.redisson.api.RLock;
  7. import org.redisson.api.RedissonClient;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.stereotype.Component;
  10. import java.lang.reflect.Method;
  11. import java.util.concurrent.TimeUnit;
  12. @Aspect
  13. @Component
  14. public class LockAdvice {
  15. @Autowired
  16. private RedissonClient rc;
  17. //execution切入点表达式@annotatio锁绝对路径
  18. @Around("execution(* *..service..*.*(..))&&@annotation(com.woniu.movie1.utils.RidissonLock)")
  19. public Object lock(ProceedingJoinPoint pjp){
  20. RLock lock=null;
  21. try {
  22. MethodSignature ms=(MethodSignature) pjp.getSignature();
  23. Method method = ms.getMethod();
  24. RidissonLock rl = method.getDeclaredAnnotation(RidissonLock.class);
  25. String className = pjp.getTarget().getClass().getName();//类的绝对路径
  26. String methodName = pjp.getSignature().getName(); //方法名
  27. lock = rc.getLock(className+":"+methodName);
  28. boolean b = lock.tryLock( rl.time(),rl.lockTimeOut(),TimeUnit.SECONDS);
  29. if(b){
  30. return pjp.proceed();//上锁成功
  31. }
  32. }catch (Throwable e){
  33. e.printStackTrace();
  34. throw new RuntimeException(e);//出现异常
  35. }finally {
  36. lock.unlock();//解锁
  37. }
  38. return null;
  39. }
  40. }

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();
    }
}