分布式锁

分布式锁redisson的简单使用

 

1)引入依赖

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    version>3.12.0</version>
</dependency>

 

2)将RedissonClient注入,并编写上锁代码

代码如下(示例):

@Autowired
private RedissonClient redissonClient;

    @ResponseBody
    @GetMapping("/hello")
    public String hello(){

        //1.获取一把锁,只要锁的名字一样,就是同一把锁
        RLock lock = redissonClient.getLock("my-lock");

        //2.加锁
        lock.lock();//阻塞式等待。默认加的锁都是30s
        //lock.lock(10, TimeUnit.SECONDS);省掉了整个续期操作,手动解锁
        try {
            System.out.println("加锁成功,执行业务"+ Thread.currentThread().getId());
            Thread.sleep(30000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            System.out.println("释放锁..."+ Thread.currentThread().getId());
            lock.unlock();
        }

        return "hello";
    }

 


  

3)测试结果

测试思路:本人使用的网关,将JMeter发送的请求发到网关上,然后将服务在不端口下启动,模拟部署在多台服务器上,当有一个正在执行的时候,其他服务只能等待该服务释放锁之后才可以执行,锁的相关数据可以到redis中去查看。
————————————————
版权声明:本文为CSDN博主「Zi昂昂昂昂昂」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/A1435900388/article/details/126194125

2.简单介绍一下redisson不同类型锁的使用

1)读写锁

@ResponseBody
    @GetMapping("/write")
    public String writeValue(){

        RReadWriteLock lock = redissonClient.getReadWriteLock("rw-lock");
        String s = null;
        RLock rLock = lock.writeLock();
        try {
            //1.改数据加写锁
            rLock.lock();
            System.out.println("写锁枷锁成功。。。"+Thread.currentThread().getId());
            s = UUID.randomUUID().toString();
            Thread.sleep(30000);
            redisTemplate.opsForValue().set("writeValue",s);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            rLock.unlock();
        }

        return s;

    }

    @ResponseBody
    @GetMapping("/read")
    public String readValue(){
        RReadWriteLock lock = redissonClient.getReadWriteLock("rw-lock");
        String s = null;
        //加读锁
        RLock rLock = lock.readLock();
        rLock.lock();
        System.out.println("读锁枷锁成功。。。"+Thread.currentThread().getId());
        try {
            s = redisTemplate.opsForValue().get("writeValue");
            Thread.sleep(30000);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            rLock.unlock();
        }

        return s;

    }

 

2)信号量

代码如下(示例):

 

   @GetMapping("/park")
    @ResponseBody
    public String park() throws InterruptedException {

        RSemaphore park = redissonClient.getSemaphore("park");
        park.acquire();//获取一个信号,获取一个值,占一个位置
        boolean b = park.tryAcquire();
        if (b){
            //执行业务
        }else {
            return "error";
        }

        return "ok";
    }

    @GetMapping("/go")
    @ResponseBody
    public String go() throws InterruptedException {

        RSemaphore park = redissonClient.getSemaphore("park");
        park.release();//释放一个信号,释放一个位置

        return "ok";
    }

 

3)闭锁

代码如下(示例):

  

 @ResponseBody
    @GetMapping("/lockDoor")
    public String lockDoor() throws InterruptedException {
        RCountDownLatch door = redissonClient.getCountDownLatch("door");
        door.trySetCount(5);
        door.await();//等待闭锁都完成

        return "放假了";
    }

    @ResponseBody
    @GetMapping("/gogogo/{id}")
    public String gogogo(@PathVariable Long id){
        RCountDownLatch door = redissonClient.getCountDownLatch("door");
        door.countDown();//计数减一

        return id+"班的人都走了...";
    }

 



 

闭锁为了方便理解我们可以举个例子,小明的学校要放假锁门了,学校一共有三个班级,只有当这三个班级都走了,才能锁门,所以执行lockDoor的时候,发现闭锁中还有三个班没有走完,每当gogogo执行一次,代表有一个班级走了,当三个班级都走完的时候我们的闭锁中值为0,lockDoor开始执行。

 


 

 

posted @ 2022-08-17 16:30  桃花雪  阅读(43)  评论(0编辑  收藏  举报