分布式锁Redisson之信号量

简介

信号量为存储在redis中的一个数字,当这个数字大于0时,即可以调用acquire()方法增加数量,也可以调用release()方法减少数量,但是当调用release()之后小于0的话方法就会阻塞,直到数字大于0

RSemaphore semaphore = redisson.getSemaphore("semaphore");
semaphore.acquire();
//或
semaphore.acquireAsync();
semaphore.acquire(23);
semaphore.tryAcquire();
//或
semaphore.tryAcquireAsync();
semaphore.tryAcquire(23, TimeUnit.SECONDS);
//或
semaphore.tryAcquireAsync(23, TimeUnit.SECONDS);
semaphore.release(10);
semaphore.release();
//或
semaphore.releaseAsync();

案例

   /**
     * 停车场
     * 三个车位
     * 当车位不够时,其他的车子只能等待车位空闲才能停车,如果车位足够时,车子入库并且空闲车位-1
     * @return
     */
    @GetMapping("/park")
    @ResponseBody
    public String park() throws InterruptedException {

        RSemaphore park = redisson.getSemaphore("park");
        park.acquire();//获取信号量 , 获取一个值, 占一个车位

        return "ok";
    }


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

        RSemaphore park = redisson.getSemaphore("park");
        park.release();//释放一个车位

        return "ok";
    }

新建key为park值为3的键值对,对应三个车位。
image

当访问/park接口就会占一个车位
image

我们这里在请求三次/park接口,看看没有车位会怎样?
可以发现只要车位不够,它就会一直阻塞等待,直到他能获取一个车位。
image
我们通过/go,释放一个车位,再去访问/park发现可以停车了,说明只要有空闲的车位,阻塞状态就会解除就会继续执行下去
image

image

  /**
     * 车库停车
     * 3车位
     * 信号量也可以做分布式限流
     */
    @GetMapping(value = "/park")
    @ResponseBody
    public String park() throws InterruptedException {

        RSemaphore park = redisson.getSemaphore("park");
        park.acquire();     //获取一个信号、获取一个值,占一个车位
        boolean flag = park.tryAcquire();

        if (flag) {
            //执行业务
        } else {
            return "error";
        }

        return "ok=>" + flag;
    }

    @GetMapping(value = "/go")
    @ResponseBody
    public String go() {
        RSemaphore park = redisson.getSemaphore("park");
        park.release();     //释放一个车位
        return "ok";
    }
posted @ 2022-11-17 20:44  长情c  阅读(536)  评论(0)    收藏  举报