Redisson实现分布式锁

 1 package com.miaoshaproject;
 2 import org.redisson.Redisson;
 3 import org.redisson.api.RLock;
 4 import org.redisson.api.RedissonClient;
 5 import org.redisson.config.Config;
 6 
 7 import java.util.concurrent.locks.Lock;
 8 import java.util.concurrent.locks.ReentrantLock;
 9 
10 /**
11  * @Author wangshuo
12  * @Date 2022/5/15, 8:52
13  * Redisson实现分布式锁:缺点是资源消耗较大
14  */
15 /*@RunWith(SpringRunner.class)
16 @SpringBootTest*/
17 public class TestRedissonLock {
18 
19     //库存数量
20     private static int num = 3;
21     //锁对象
22     private static Lock lock = new ReentrantLock();
23     //Redisson锁
24     private static RLock lock1;
25 
26     public static void main(String[] args) {
27         stockThread();
28     }
29     public static void stockThread() {
30 
31         set();
32 
33         for (int i = 0; i < 5; i++) {
34 
35             new Thread(() -> {
36 
37                 lock1.lock();
38                 //调用减少库存的方法
39                 boolean b = reduceStock();
40                 lock1.unlock();
41                 if (b)
42                     System.out.println(Thread.currentThread().getName() + "减少库存成功");
43                 else
44                     System.out.println(Thread.currentThread().getName() + "减少库存失败");
45             },"Thread" + i).start();
46         }
47     }
48 
49     //减少库存的方法
50     public static boolean reduceStock() {
51         if (num > 0) {
52             try {
53                 Thread.sleep(1000);
54             } catch (InterruptedException e) {
55                 e.printStackTrace();
56             }
57             num--;
58             return true;
59         } else
60             return false;
61     }
62 
63     public static void set() {
64         Config config = new Config();
65         config.useSingleServer().setAddress("redis://127.0.0.1:6379").setDatabase(0);
66         RedissonClient redissonClient = Redisson.create(config);
67         lock1 = redissonClient.getLock("lock1");
68     }
69 }

原生redis实现分布式锁

· RedisLock

 1 package com.miaoshaproject.util.lock;
 2 
 3 import com.miaoshaproject.util.redis.RedisUtil;
 4 import org.redisson.api.RLock;
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.data.redis.core.RedisTemplate;
 7 import org.springframework.stereotype.Component;
 8 
 9 import java.util.concurrent.TimeUnit;
10 import java.util.concurrent.locks.Condition;
11 import java.util.concurrent.locks.Lock;
12 import java.util.concurrent.locks.ReentrantLock;
13 
14 /**
15  * @Author wangshuo
16  * @Date 2022/5/15, 15:16
17  * Please add a comment
18  */
19 @Component
20 public class RedisLock implements Lock {
21 
22     @Autowired
23     RedisTemplate redisTemplate;
24     private String key;
25 
26     //对外提供私有key变量赋值
27     //这里使用了@Component对外提供Bean,
28     //  我们也可以使用装饰器设计模式,使需要用锁的类继承RedisLock类,重写lock和unlock方法
29     public void setKey(String key) {
30         this.key = key;
31     }
32 
33     @Override
34     public void lock() {
35 
36         while (true) {
37 
38             //分布式事务保证安全性,使用redis作为锁标识
39             //每个key都要不一样
40             boolean setnx = redisTemplate.opsForValue().setIfAbsent(key, "Value", 5,TimeUnit.SECONDS);//设置5秒过期
41             if (setnx)
42                 return;
43             else
44                 System.out.println(Thread.currentThread().getName() + "等待中");
45         }
46     }
47 
48     @Override
49     public void lockInterruptibly() throws InterruptedException {
50 
51     }
52 
53     @Override
54     public boolean tryLock() {
55         return false;
56     }
57 
58     @Override
59     public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
60         return false;
61     }
62 
63     @Override
64     public void unlock() {
65 
66         redisTemplate.delete("LockName");
67     }
68 
69     @Override
70     public Condition newCondition() {
71         return null;
72     }
73 }

 

· TestRedisLock

 

 1    @Autowired
 2     RedisUtil redisUtil;
 3     @Autowired
 4     RedisLock redisLock;
 5     //库存数量
 6     private static int num = 3;
 7    //测试redis实现分布式锁
 8     @RequestMapping(value = "testredis")
 9     @ResponseBody
10     public Map<String,String> testRedis() throws InterruptedException {
11         HashMap<String, String> map = new HashMap<>();
12 
13         StringBuilder sb = new StringBuilder();
14         sb.append(this.getClass().getName()).append(Thread.currentThread().getStackTrace()[1].getMethodName());
15         String s = sb.toString().replace(".", "");
16         redisLock.setKey(s);
17         for (int i = 0; i < 5; i++) {
18 
19             new Thread(() -> {
20 
21                 redisLock.lock();
22                 //调用减少库存的方法
23                 boolean b = reduceStock();
24                 redisLock.unlock();
25                 if (b)
26                     map.put(Thread.currentThread().getName(), "减少库存成功");
27                 else
28                     System.out.println(Thread.currentThread().getName() + "减少库存失败");
29             }, "Thread" + i).start();
30         }
31 
32         Thread.sleep(10000);
33         return map;
34     }