likes
comments
collection
share

Redisson《四:信号量》

作者站长头像
站长
· 阅读数 23

官简介:

基于Redis的Redisson的分布式信号量(Semaphore)Java对象RSemaphore采用了与java.util.concurrent.Semaphore相似的接口和用法。同时还提供了异步(Async)反射式(Reactive)RxJava2标准的接口。

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

基于Redis的Redisson可过期性信号量(PermitExpirableSemaphore)是在RSemaphore对象的基础上,为每个信号增加了一个过期时间。每个信号可以通过独立的ID来辨识,释放时只能通过提交这个ID才能释放。它提供了异步(Async)反射式(Reactive)RxJava2标准的接口。

RPermitExpirableSemaphore semaphore = redisson.getPermitExpirableSemaphore("mySemaphore");
String permitId = semaphore.acquire();
// 获取一个信号,有效期只有2秒钟。
String permitId = semaphore.acquire(2, TimeUnit.SECONDS);
// ...
semaphore.release(permitId);

一:测试信号量

编写代码如下

/**
 * 测试信号量
 */
@GetMapping("/acquire")
@ResponseBody
public String acquire() throws InterruptedException {
    RSemaphore semaphore = redissonClient.getSemaphore("Semaphore-test");
    semaphore.acquire();
    System.out.println("获取到信号量锁,开始执行业务---》");
    return "ok";
}
@ResponseBody
@GetMapping("/release")
public String release(){
    RSemaphore semaphore = redissonClient.getSemaphore("Semaphore-test");
    semaphore.release();
    System.out.println("开始释放---》");
    return "ok";
}

提前在redis中设置好key为Semaphore-test的值为5,如下图所示:

Redisson《四:信号量》 启动项目,打开浏览器开始测试

Redisson《四:信号量》 我们发现当Semaphore-test值为0时,再执行acquire操作时,就会一直阻塞,直到程序调用了release后,Semaphore-test的值大于0,acquire才会又继续执行

Redisson《四:信号量》

二:tryAcquire方式

/**
 * 测试信号量
 */
@GetMapping("/acquire")
@ResponseBody
public String acquire() throws InterruptedException {
    RSemaphore semaphore = redissonClient.getSemaphore("Semaphore-test");
    boolean b = semaphore.tryAcquire();
    if(b){
        System.out.println("获取到信号量锁,开始执行业务---》");
        return "ok";
    }
    return "ok---->"+b;
}
@ResponseBody
@GetMapping("/release")
public String release(){
    RSemaphore semaphore = redissonClient.getSemaphore("Semaphore-test");
    semaphore.release();
    System.out.println("开始释放---》");
    return "ok";
}

tryAcquire方式返回的是Boolean,可以通过判断Boolean值来确认是否可以执行业务

信号量使用场景:常用作分布式限流

转载自:https://juejin.cn/post/7000540815789883399
评论
请登录